/* LexForge workspace — component system.
   Implements the "LexForge Workspace" design prototype. Every value here comes
   from workspace-ui.css tokens; there are no raw hex colours below.

   New components use the lfw- prefix. Legacy hooks that JavaScript depends on
   (.shell, main.main, header.topbar, .sb-firm, .auth-gate, .demo-panel, .pill,
   .stat, .btn …) keep their names and are restyled in place. */

/* ==========================================================================
   1. App shell
   A bounded frame, NOT a scrolling document. Root is height:100vh with
   overflow:hidden; only the content pane scrolls, so the sidebar and top bar
   stay pinned. Using min-height:100vh here instead scrolls the whole document,
   unpins the chrome and silently disables the top bar's scroll shadow.
   ========================================================================== */

body.lfw { margin: 0; min-width: 320px; }

.shell {
  display: flex;
  height: 100vh;
  overflow: hidden;
  background: var(--bg);
}

main.main {
  display: flex;
  flex: 1;
  min-width: 0;
  min-height: 0;
  flex-direction: column;
}

.lfw-pane {
  flex: 1;
  padding: 34px 32px 64px;
  overflow: auto;
}

.lfw-content { max-width: 1140px; margin: 0 auto; }

/* Team is capped tighter than the rest. */
.lfw-content.is-narrow { max-width: 820px; }

.lfw-view {
  display: flex;
  flex-direction: column;
  gap: 22px;
  animation: pageIn .32s var(--ease);
}

/* --- Sidebar (250px fixed) ------------------------------------------------ */

.sidebar {
  display: flex;
  flex: 0 0 250px;
  width: 250px;
  flex-direction: column;
  padding: 20px 16px 16px;
  border-right: 1px solid var(--line);
  background: var(--sidebar);
  overflow-y: auto;
}

.lfw-brand {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 4px 18px;
}

.lfw-wordmark {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: -.01em;
  text-decoration: none;
}
.lfw-wordmark:hover { color: var(--ink); text-decoration: none; }

/* The workspace label. In the prototype this is static text (single-tenant);
   here it is the workspace switcher auth.js binds to via .sb-firm, styled to
   read as the prototype's label rather than a control. */
.sb-firm {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 8px;
  padding: 3px 4px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  text-align: left;
}
.sb-firm:hover { background: var(--nav-hover); }

.lfw-workspace-mark {
  display: flex;
  width: 20px;
  height: 20px;
  flex: 0 0 20px;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  background: var(--avatar-bg);
  color: var(--avatar-fg);
  font-size: 10.5px;
  font-weight: 600;
}

.lfw-workspace-name {
  overflow: hidden;
  flex: 1;
  min-width: 0;
  color: var(--ink-3);
  font-size: 13px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wd-nav { display: flex; flex-direction: column; gap: 2px; }

.wd-nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 9px;
  color: var(--ink-3);
  font-size: 13.5px;
  font-weight: 500;
  text-decoration: none;
}
.wd-nav a:hover { background: var(--nav-hover); color: var(--ink-3); text-decoration: none; }
.wd-nav a[aria-current="page"] { background: var(--nav-bg); color: var(--nav-fg); font-weight: 600; }

.wd-nav a svg {
  width: 20px;
  height: 20px;
  flex: 0 0 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.wd-nav a .lfw-nav-label { flex: 1; }

.lfw-nav-count {
  padding: 1px 7px;
  border-radius: 20px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.lfw-sidebar-spacer { flex: 1; min-height: 24px; }

.demo-plan {
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card-alt);
}

.demo-plan .plan {
  color: var(--muted-2);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* workspace-api.js writes into `.sb-usage .lbl span` by index — labels[0] gets
   "<b>8,647</b> pages left", labels[1] gets "of 10,000". The prototype puts the
   figure ABOVE the track and the cycle line BELOW it, so `.lbl` is dissolved
   with display:contents and the four children are ordered on the grid. Keeping
   the DOM order intact is what lets the existing JS keep working untouched. */
.sb-usage {
  display: grid;
  align-items: baseline;
  grid-template-columns: 1fr auto;
  gap: 9px 8px;
}

.sb-usage .lbl { display: contents; }

.sb-usage .lbl span:first-child {
  order: 1;
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: 12.5px;
}

.sb-usage .lbl span:first-child b {
  margin-right: 2px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 23px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}

.sb-usage .bar {
  order: 2;
  grid-column: 1 / -1;
  height: 4px;
  overflow: hidden;
  border-radius: 4px;
  background: var(--track);
}

.sb-usage .usage-fill {
  display: block;
  width: 0;
  height: 100%;
  border-radius: 4px;
  background: var(--accent);
  transform-origin: left;
  animation: barIn 1s var(--ease);
}

.sb-usage .lbl span:nth-child(2) {
  order: 3;
  grid-column: 1;
  color: var(--muted-2);
  font-size: 11.5px;
}

.sb-pricing-link {
  order: 3;
  grid-column: 2;
  font-size: 11.5px;
  font-weight: 500;
  text-align: right;
}

/* The whole plan card opens Billing (Dan, 2026-09-13). "Change plan" stays the
   card's only link: its ::after layer stretches over the card, so a click
   anywhere lands on it while keyboard and screen-reader users still meet one
   ordinary link. Before this the plan label looked clickable — it shares
   .sb-firm's pointer and hover with the workspace switcher — but did nothing. */
.demo-plan { position: relative; }

.demo-plan .sb-pricing-link::after {
  position: absolute;
  inset: 0;
  content: "";
}

.demo-plan:hover { border-color: var(--focus); }

.sb-foot { display: flex; gap: 14px; padding: 14px 6px 2px; flex-wrap: wrap; }

.sb-foot a,
.sb-foot button {
  padding: 0;
  border: 0;
  background: none;
  color: var(--muted-2);
  cursor: pointer;
  font: inherit;
  font-size: 11.5px;
  text-decoration: none;
}
.sb-foot a:hover,
.sb-foot button:hover { color: var(--ink); text-decoration: none; }

/* --- Top bar (57px fixed) ------------------------------------------------- */

header.topbar {
  display: flex;
  position: relative;
  z-index: 2;
  height: 57px;
  flex: 0 0 57px;
  align-items: center;
  gap: 14px;
  padding: 0 32px;
  border-bottom: 1px solid var(--line-mid);
  background: var(--bg);
  transition: box-shadow .2s ease;
}

.lfw-topbar-spacer { flex: 1; }

/* The theme switch is two plain buttons whose active/inactive appearance comes
   from tokens the theme itself flips. No component state, so the control cannot
   get out of sync with the theme. */
.demo-theme-toggle {
  display: flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card-alt);
}

.demo-theme-toggle button {
  display: flex;
  width: 30px;
  height: 26px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
}

.demo-theme-toggle button svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.demo-theme-toggle [data-theme-set="light"] { background: var(--sun-bg); color: var(--sun-fg); }
.demo-theme-toggle [data-theme-set="dark"] { background: var(--moon-bg); color: var(--moon-fg); }

.demo-avatar {
  display: flex;
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--avatar-bg);
  color: var(--avatar-fg);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
}

/* ==========================================================================
   2. Page header
   ========================================================================== */

.lfw-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
}

.lfw-head-text { display: flex; flex-direction: column; gap: 5px; }

.lfw-head h1 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 33px;
  font-weight: 500;
  letter-spacing: -.015em;
  line-height: 1.1;
}

.lfw-head p {
  margin: 0;
  color: var(--muted);
  font-size: 14px;
  text-wrap: pretty;
}

.lfw-head-actions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.lfw-meta-line {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted-2);
  font-size: 12.5px;
  flex-wrap: wrap;
}
.lfw-meta-line .sep { color: var(--line); }

.lfw-seats { color: var(--muted-2); font-size: 12.5px; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   3. Buttons
   ========================================================================== */

.btn,
.demo-button {
  display: inline-flex;
  height: 37px;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 0 16px;
  border: 0;
  border-radius: 9px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  cursor: pointer;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  text-decoration: none;
  transition: transform .14s ease, background-color .24s ease, border-color .24s ease;
}
.btn:hover,
.demo-button:hover { background: var(--btn-hover); color: var(--btn-fg); text-decoration: none; transform: translateY(-1px); }
.btn:active,
.demo-button:active { transform: translateY(0); }

.btn svg,
.demo-button svg {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.btn.ghost,
.demo-button-secondary {
  padding: 0 14px;
  border: 1px solid var(--btn-line);
  background: transparent;
  color: var(--ink-2);
}
.btn.ghost:hover,
.demo-button-secondary:hover { background: var(--btn-ghost-hover); color: var(--ink-2); transform: none; }

.btn.sm { height: 34px; padding: 0 13px; font-size: 12.5px; }
.btn.ghost.sm { padding: 0 12px; }

/* Row actions are deliberately quiet: six solid buttons in a column previously
   outweighed the page's own primary call to action. */
.btn.row {
  height: 30px;
  padding: 0 11px;
  border: 1px solid var(--btn-line);
  border-radius: 8px;
  background: transparent;
  color: var(--ink-2);
  font-size: 12.5px;
}
.btn.row:hover { background: var(--btn-ghost-hover); color: var(--ink-2); transform: none; }
.btn.row.is-retry { border-color: var(--danger-btn-line); color: var(--fail-fg); }
.btn.row.is-cancel { opacity: .6; }

.btn.icon {
  width: 37px;
  height: 37px;
  padding: 0;
  border: 1px solid var(--btn-line);
  background: transparent;
  color: var(--ink-3);
}
.btn.icon:hover { background: var(--btn-ghost-hover); color: var(--ink-3); transform: none; }
.btn.icon svg { width: 15px; height: 15px; flex-basis: 15px; stroke-width: 1.4; }

.btn.quiet {
  height: 34px;
  padding: 0 6px;
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: 12.5px;
}
.btn.quiet:hover { background: transparent; color: var(--ink); transform: none; }

.btn.danger.quiet { color: var(--danger-body); }
.btn.danger.quiet:hover { color: var(--fail-fg); }

.btn.danger {
  border: 1px solid var(--danger-btn-line);
  background: transparent;
  color: var(--fail-fg);
}
.btn.danger:hover { background: var(--danger-btn-hover); color: var(--fail-fg); transform: none; }

/* Disabled is flat and non-interactive, never a dimmed primary. */
.btn:disabled,
.btn[aria-disabled="true"],
.demo-button:disabled {
  background: var(--flat-bg);
  color: var(--faintest);
  cursor: default;
  transform: none;
}
.btn:disabled:hover,
.btn[aria-disabled="true"]:hover,
.demo-button:disabled:hover { background: var(--flat-bg); color: var(--faintest); transform: none; }
.btn.ghost:disabled { border-color: var(--line); background: transparent; }

/* .style-confirm-change joins the group rather than redeclaring it: the restyle
   left it with font-size and weight only, so it rendered as a bare <button> —
   the browser's default grey box — where console.css had a text link. */
.lnk,
.demo-link-button,
.style-confirm-change {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
}
.lnk:hover,
.demo-link-button:hover,
.style-confirm-change:hover { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }

.lfw-arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 500;
}
.lfw-arrow-link svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ==========================================================================
   4. Cards and panels
   ========================================================================== */

.demo-panel,
.panel,
.card,
.lfw-card {
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: var(--card-shadow);
}

.lfw-card.is-clipped,
.demo-panel.is-clipped { overflow: hidden; }

.lfw-card-pad { padding: 18px 20px; }

.demo-panel-head,
.panel-head,
.lfw-card-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 20px 15px;
  flex-wrap: wrap;
}

.lfw-card-head h2,
.demo-panel-head h2,
.panel-head h2,
.lfw-card h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -.01em;
}

.lfw-card h3,
.lfw-subcard-title {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -.01em;
}

.lfw-card-head .sub,
.lfw-card .sub {
  margin: 0;
  color: var(--muted-2);
  font-size: 12.5px;
}

.lfw-card-foot,
.lfw-panel-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 13px 20px;
  color: var(--faint);
  font-size: 12px;
  flex-wrap: wrap;
}

/* Inset footer strip — plan hints, save bars. */
.lfw-card-strip {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  border-top: 1px solid var(--line-mid);
  background: var(--card-alt);
  flex-wrap: wrap;
}
.lfw-card-strip svg {
  width: 15px;
  height: 15px;
  flex: 0 0 15px;
  color: var(--accent);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.lfw-card-strip p {
  flex: 1;
  min-width: 200px;
  margin: 0;
  color: var(--muted);
  font-size: 12.5px;
  text-wrap: pretty;
}

.lfw-divider { height: 1px; background: var(--line-mid); }

/* ==========================================================================
   5. Stat tiles
   ========================================================================== */

.stats,
.lfw-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 14px;
}
/* Says what the tiles above are counting whenever that is not the whole
   workspace (QA 2026-08-26, F-16). */
.lfw-stats-scope {
  margin: 10px 0 0;
  color: var(--muted-2);
  font-size: 12px;
}

.stat,
.lfw-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 15px 17px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--card);
  box-shadow: var(--card-shadow);
}

.stat .l,
.lfw-stat .l {
  color: var(--muted-2);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.stat .v,
.lfw-stat .v {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 26px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}

.stat .v.is-ok,
.lfw-stat .v.is-ok { color: var(--ok-fg); }

.stat .d,
.lfw-stat .d { color: var(--faint); font-size: 12px; line-height: 1.45; }

/* ==========================================================================
   6. Filter chips
   ========================================================================== */

.lfw-chips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.lfw-chip {
  display: flex;
  height: 27px;
  align-items: center;
  gap: 6px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
  transition: transform .14s ease, background-color .24s ease, border-color .24s ease;
}
.lfw-chip:hover { border-color: var(--focus); }
.lfw-chip:active { transform: scale(.96); }

.lfw-chip .n { color: var(--faint); font-size: 11px; font-variant-numeric: tabular-nums; }

.lfw-chip[aria-pressed="true"] {
  border-color: var(--btn-bg);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-weight: 600;
}
.lfw-chip[aria-pressed="true"] .n { color: var(--btn-fg); opacity: .72; }

/* Neutral, non-interactive chip — "You", "4 runs". */
.lfw-tag {
  flex: 0 0 auto;
  padding: 1px 7px;
  border-radius: 20px;
  background: var(--chip-bg);
  color: var(--chip-fg);
  font-size: 11px;
  font-weight: 500;
}

/* ==========================================================================
   7. Status pills
   ========================================================================== */

.pill,
.demo-status,
.lfw-pill {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 6px;
  padding: 3px 9px 3px 8px;
  border: 0;
  border-radius: 20px;
  background: var(--flat-bg);
  color: var(--flat-fg);
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}

.pill .pdot,
.demo-status .pdot,
.lfw-pill .pdot {
  width: 5px;
  height: 5px;
  flex: 0 0 5px;
  border-radius: 50%;
  background: currentColor;
}

.pill.is-ready, .pill.ok, .demo-status-ready, .lfw-pill.is-ready { background: var(--ok-bg); color: var(--ok-fg); }
.pill.is-review, .pill.warn, .demo-status-review, .lfw-pill.is-review { background: var(--warn-bg); color: var(--warn-fg); }
.pill.is-processing, .demo-status-running, .lfw-pill.is-processing { background: var(--proc-bg); color: var(--proc-fg); }
.pill.is-failed, .pill.danger, .demo-status-failed, .lfw-pill.is-failed { background: var(--fail-bg); color: var(--fail-fg); }
.pill.neutral, .lfw-pill.is-neutral { background: var(--flat-bg); color: var(--flat-fg); }
.pill.is-info, .pill.info { background: var(--accent-soft); color: var(--accent-ink); }

.pill.is-processing .pdot,
.demo-status-running .pdot,
.lfw-pill.is-processing .pdot { animation: pulseDot 1.4s ease-in-out infinite; }

/* Badge form used on house-style cards. */
.lfw-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px 2px 6px;
  border-radius: 20px;
  background: var(--ok-bg);
  color: var(--ok-fg);
  font-size: 11px;
  font-weight: 600;
}
.lfw-badge svg {
  width: 11px;
  height: 11px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.lfw-badge.is-default { padding: 2px 8px; background: var(--accent-soft); color: var(--accent-ink); }
.lfw-badge.is-warn { background: var(--warn-bg); color: var(--warn-fg); }
.lfw-badge.is-failed { background: var(--fail-bg); color: var(--fail-fg); }

/* ==========================================================================
   8. Grid tables
   The min-width floor matters: without it the fixed tracks exceed a narrow
   pane and collapse the first column to zero.
   ========================================================================== */

.lfw-table-wrap { overflow-x: auto; }

.lfw-thead,
.lfw-row {
  display: grid;
  align-items: center;
  gap: 12px;
}

.lfw-thead {
  padding: 9px 20px;
  border-top: 1px solid var(--line-mid);
  border-bottom: 1px solid var(--line-mid);
  background: var(--thead);
  color: var(--muted-2);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.lfw-row {
  padding: 13px 20px;
  border-bottom: 1px solid var(--line-soft);
  animation: rowIn .32s var(--ease) both;
}
.lfw-row:hover { background: var(--row-hover); }

/* Reconstructions / Documents */
.lfw-grid-conversions { grid-template-columns: minmax(180px, 1fr) 60px 150px 190px 108px; min-width: 820px; }
/* Change reports */
.lfw-grid-reports { grid-template-columns: minmax(200px, 1fr) 132px 64px 96px 150px; min-width: 800px; }

.lfw-cell-doc { display: flex; min-width: 0; flex-direction: column; gap: 3px; }

.lfw-doc-name {
  overflow: hidden;
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 500;
  text-decoration: none;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lfw-doc-name:hover { color: var(--accent); text-decoration: none; }

/* The metadata line is the fix for indistinguishable rows. It is not decoration
   — it is omitted entirely when there is no real timestamp or owner to show. */
.lfw-doc-meta {
  overflow: hidden;
  color: var(--faint);
  font-size: 11.5px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lfw-cell-num { color: var(--ink-3); font-size: 13px; font-variant-numeric: tabular-nums; text-align: right; }
.lfw-cell-text { overflow: hidden; color: var(--ink-3); font-size: 13px; text-overflow: ellipsis; white-space: nowrap; }
.lfw-cell-when { overflow: hidden; color: var(--muted); font-size: 12.5px; text-overflow: ellipsis; white-space: nowrap; }
.lfw-cell-actions { display: flex; justify-content: flex-end; }

.lfw-cell-num.is-none { color: var(--faintest); }
.lfw-cell-num.is-high { color: var(--warn-fg); font-weight: 600; }
.lfw-cell-num.is-plain { color: var(--ink-2); }

.lfw-cell-status { display: flex; min-width: 0; flex-direction: column; gap: 5px; }

.lfw-status-note { color: var(--faint); font-size: 11.5px; }

.lfw-progress-row { display: flex; align-items: center; gap: 8px; }

.lfw-progress {
  position: relative;
  width: 96px;
  height: 3px;
  overflow: hidden;
  border-radius: 3px;
  background: var(--track);
}
.lfw-progress i {
  display: block;
  height: 100%;
  background: var(--accent);
  transform-origin: left;
  animation: barIn .9s var(--ease);
}
.lfw-progress::after {
  position: absolute;
  inset: 0;
  width: 34%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .5), transparent);
  animation: shimmer 1.9s linear infinite;
  content: "";
}

.lfw-check {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--ok-fg);
  font-size: 12.5px;
}
.lfw-check svg {
  width: 13px;
  height: 13px;
  flex: 0 0 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.lfw-check.is-muted { color: var(--faintest); }

.lfw-empty {
  padding: 34px 20px;
  color: var(--faint);
  font-size: 13px;
  text-align: center;
}

/* ==========================================================================
   9. Dropzone bar
   ========================================================================== */

.lfw-dropzone {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 16px 20px;
  border: 1.5px dashed var(--dash);
  border-radius: 14px;
  background: var(--dz-bg);
  cursor: pointer;
  flex-wrap: wrap;
  transition: transform .18s ease, background-color .24s ease, border-color .24s ease;
}
.lfw-dropzone:hover,
.lfw-dropzone.is-dragging { border-color: var(--dash-hover); background: var(--dz-hover); transform: translateY(-2px); }

.lfw-dz-icon {
  display: flex;
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent-soft);
}
.lfw-dz-icon svg {
  width: 17px;
  height: 17px;
  color: var(--accent);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.lfw-dz-copy { display: flex; flex: 1; min-width: 200px; flex-direction: column; gap: 2px; }
.lfw-dz-copy .t { color: var(--ink); font-size: 14.5px; font-weight: 500; }
.lfw-dz-copy .s { color: var(--muted-2); font-size: 12.5px; }

.lfw-dz-hint {
  display: flex;
  max-width: 270px;
  flex: 0 0 auto;
  align-items: flex-start;
  gap: 7px;
  color: var(--muted-2);
  font-size: 12px;
  line-height: 1.45;
}
.lfw-dz-hint svg {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
  margin-top: 1px;
  color: var(--faintest);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
}

/* ==========================================================================
   10. House style cards
   ========================================================================== */

/* The loading line sits where the cards will be, so it spans the whole grid
   rather than pretending to be a card (Dan, 2026-08-27). */
.hs-grid-loading {
  grid-column: 1 / -1;
  margin: 0;
  padding: 18px 2px;
  color: var(--muted-2);
  font-size: 13px;
}
.house-style-card-grid,
.lfw-style-grid {
  display: grid;
  align-items: stretch;
  grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
  gap: 18px;
}

.house-style-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: var(--card-shadow);
}
.house-style-card:hover { border-color: var(--focus); box-shadow: 0 10px 26px rgba(0, 0, 0, .07); }

.house-style-name {
  overflow: hidden;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -.01em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lfw-style-badges { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.house-style-meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 14px;
  font-size: 12.5px;
}
.house-style-meta dt,
.house-style-meta .k { margin: 0; color: var(--faint); }
.house-style-meta dd,
.house-style-meta .v {
  overflow: hidden;
  margin: 0;
  color: var(--ink-2);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.house-style-meta .v.is-empty { color: var(--faint); }

.lfw-rules { display: flex; flex-direction: column; gap: 8px; }

.lfw-rules-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.lfw-rules-head .t {
  color: var(--muted-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.lfw-rules-head .n { color: var(--faint); font-size: 11.5px; font-variant-numeric: tabular-nums; }

.house-style-rule-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 8px 8px 11px;
  border: 1px solid var(--line-mid);
  border-radius: 9px;
  background: var(--card-alt);
}
.house-style-rule-text { flex: 1; min-width: 0; color: var(--ink-2); font-size: 13px; }

.lfw-x {
  display: flex;
  width: 22px;
  height: 22px;
  flex: 0 0 22px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted-2);
  cursor: pointer;
}
.lfw-x:hover { background: var(--btn-ghost-hover); color: var(--ink); }
.lfw-x svg {
  width: 11px;
  height: 11px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.lfw-rules-empty {
  padding: 10px 11px;
  border: 1px dashed var(--line);
  border-radius: 9px;
  color: var(--faint);
  font-size: 12.5px;
}

/* Input and Add sit on ONE row — previously stacked with the counter orphaned
   between them. */
.house-style-rule-input { display: flex; gap: 8px; }
.house-style-rule-input input { flex: 1; min-width: 0; height: 34px; }
.house-style-rule-input .btn { flex: 0 0 auto; }

.house-style-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 2px;
  flex-wrap: wrap;
}
/* Delete is separated from the constructive actions rather than sitting fourth
   in a row of equals. */
.house-style-actions .lfw-push { flex: 1; }

.lfw-card-spacer { flex: 1; min-height: 4px; }

.house-style-card-add,
.demo-add-style {
  display: flex;
  min-height: 260px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 24px;
  border: 1.5px dashed var(--dash);
  border-radius: 16px;
  background: var(--dz-bg);
  cursor: pointer;
  transition: transform .18s ease, background-color .24s ease, border-color .24s ease;
}
.house-style-card-add:hover,
.demo-add-style:hover { border-color: var(--dash-hover); background: var(--dz-hover); transform: translateY(-2px); }

.house-style-card-add .ic,
.demo-add-style .ic {
  display: flex;
  width: 38px;
  height: 38px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent-soft);
}
.house-style-card-add .ic svg,
.demo-add-style .ic svg {
  width: 16px;
  height: 16px;
  color: var(--accent);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
}
.house-style-card-add .t,
.demo-add-style .t { color: var(--ink-2); font-family: var(--serif); font-size: 16.5px; font-weight: 500; }
.house-style-card-add .s,
.demo-add-style .s {
  max-width: 220px;
  color: var(--muted-2);
  font-size: 12.5px;
  line-height: 1.45;
  text-align: center;
}

/* ==========================================================================
   11. Forms
   ========================================================================== */

.lfw-field { display: flex; flex-direction: column; gap: 6px; }

.lfw-label,
.flbl {
  color: var(--muted-2);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
}

input[type="text"].lfw-input,
input[type="email"].lfw-input,
input[type="search"].lfw-input,
input[type="url"].lfw-input,
.settings-input,
.fin,
.lfw-input,
select.lfw-input,
textarea.lfw-input {
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--input-bg);
  color: var(--ink);
  font-size: 13.5px;
  outline: none;
}
.lfw-input:focus,
.settings-input:focus,
.fin:focus { border-color: var(--focus); }

textarea.lfw-input { height: auto; min-height: 84px; padding: 10px 12px; line-height: 1.5; resize: vertical; }

.lfw-hint { color: var(--faint); font-size: 11.5px; }

.lfw-field-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
}

.lfw-card-grid {
  display: grid;
  align-items: stretch;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 18px;
}

/* Search + filter bar */
.lfw-filter {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 20px;
  flex-wrap: wrap;
}
.lfw-filter .find {
  display: flex;
  width: 260px;
  max-width: 100%;
  height: 34px;
  align-items: center;
  gap: 9px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--input-bg);
}
.lfw-filter .find:focus-within { border-color: var(--focus); }
.lfw-filter .find svg {
  width: 14px;
  height: 14px;
  flex: 0 0 14px;
  color: var(--muted-2);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
}
.lfw-filter .find input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-size: 13px;
  outline: none;
}
.lfw-filter select.fin { height: 34px; padding: 0 10px; font-size: 12.5px; }
.lfw-filter .spacer { flex: 1; }

/* Segmented control */
.demo-segmented,
.lfw-segmented {
  display: inline-flex;
  align-self: flex-start;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card-alt);
}
.demo-segmented button,
.lfw-segmented button {
  height: 30px;
  padding: 0 14px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
}
.demo-segmented button[aria-pressed="true"],
.lfw-segmented button[aria-pressed="true"] { background: var(--accent); color: var(--btn-fg); font-weight: 600; }

/* Toggle switch */
.demo-switch,
.lfw-switch {
  display: flex;
  width: 44px;
  height: 26px;
  flex: 0 0 44px;
  justify-content: flex-start;
  padding: 3px;
  border: 0;
  border-radius: 20px;
  background: var(--dash);
  cursor: pointer;
}
.demo-switch[aria-checked="true"],
.lfw-switch[aria-checked="true"] { background: var(--accent); }
.demo-switch i,
.lfw-switch i {
  display: block;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--knob);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .28);
  transform: translateX(0);
  transition: transform .22s var(--ease);
}
.demo-switch[aria-checked="true"] i,
.lfw-switch[aria-checked="true"] i { transform: translateX(18px); }

/* Checkbox-backed variant. settings.js drives a real <input type="checkbox">,
   so the switch is drawn from :checked rather than an aria-checked button. */
.lfw-switch-wrap {
  display: flex;
  width: 44px;
  height: 26px;
  flex: 0 0 44px;
  justify-content: flex-start;
  padding: 3px;
  border-radius: 20px;
  background: var(--dash);
  cursor: pointer;
}
.lfw-switch-wrap input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.lfw-switch-wrap i {
  display: block;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--knob);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .28);
  transform: translateX(0);
  transition: transform .22s var(--ease);
}
.lfw-switch-wrap:has(input:checked) { background: var(--accent); }
.lfw-switch-wrap:has(input:checked) i { transform: translateX(18px); }
.lfw-switch-wrap:has(input:disabled) { cursor: default; opacity: .6; }
.lfw-switch-wrap:has(input:focus-visible) { outline: 2px solid var(--ring); outline-offset: 2px; }

.lfw-toggle-row { display: flex; align-items: center; gap: 14px; }
.lfw-toggle-row .t { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 2px; }
.lfw-toggle-row .t b { color: var(--ink); font-size: 13.5px; font-weight: 500; }
.lfw-toggle-row .t span { color: var(--faint); font-size: 12px; }

/* Definition rows — Data region, plan facts. */
.lfw-defs { display: flex; flex-direction: column; }
.lfw-defs > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: 12.5px;
}
.lfw-defs > div:last-child { border-bottom: 0; }
.lfw-defs .k { color: var(--muted); }
.lfw-defs .v { color: var(--ink); font-weight: 500; text-align: right; }
.lfw-defs .v.is-ok { color: var(--ok-fg); }

.lfw-note { margin: 0; color: var(--faint); font-size: 12px; line-height: 1.5; text-wrap: pretty; }
.lfw-foot-note { color: var(--faint); font-size: 11.5px; }

.lfw-figure { display: flex; align-items: baseline; gap: 6px; }
.lfw-figure b {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 24px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}
.lfw-figure span { color: var(--muted); font-size: 12.5px; }

.lfw-track { height: 4px; overflow: hidden; border-radius: 4px; background: var(--track); }
.lfw-track i {
  display: block;
  height: 100%;
  border-radius: 4px;
  background: var(--accent);
  transform-origin: left;
  animation: barIn 1s var(--ease);
}

.lfw-links { display: flex; gap: 16px; flex-wrap: wrap; }
.lfw-links a { font-size: 12.5px; font-weight: 500; }

/* ==========================================================================
   12. Danger card
   ========================================================================== */

.settings-danger,
.lfw-danger {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 18px 20px;
  border: 1px solid var(--danger-line);
  border-radius: 16px;
  background: var(--danger-bg);
  flex-wrap: wrap;
}
.settings-danger .t,
.lfw-danger .t { display: flex; flex: 1; min-width: 240px; flex-direction: column; gap: 3px; }
.settings-danger h2,
.lfw-danger h2 {
  margin: 0;
  color: var(--danger-title);
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -.01em;
}
.settings-danger p,
.lfw-danger p { margin: 0; color: var(--danger-body); font-size: 12.5px; text-wrap: pretty; }

/* ==========================================================================
   13. Modal
   ========================================================================== */

.lfw-modal-overlay,
.scrim,
.hs-upload-scrim,
.team-invite-backdrop {
  display: flex;
  position: fixed;
  z-index: 60;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(18, 14, 10, .58);
  backdrop-filter: blur(2px);
  inset: 0;
}
/* These three took the layout half of .style-sheet-backdrop but not its tint,
   so the JS-built house-style dialogs and team.html's invite dialog floated
   over undimmed content while the reconstructions modal dimmed correctly
   (QA 2026-08-26, F-09). The reduced-transparency query further down already
   lists all four as if they had a backdrop-filter, so the pair was dropped
   rather than withheld. One overlay ships a dedicated .lfw-modal-backdrop
   child as its click target; it keeps that and must not be tinted twice. */
.scrim:has(> .lfw-modal-backdrop),
.hs-upload-scrim:has(> .lfw-modal-backdrop),
.team-invite-backdrop:has(> .lfw-modal-backdrop) {
  background: none;
  backdrop-filter: none;
}

.lfw-modal-backdrop {
  position: absolute;
  background: rgba(18, 14, 10, .58);
  animation: fadeIn .18s ease;
  backdrop-filter: blur(2px);
  inset: 0;
}

.lfw-modal,
.hs-upload-modal,
.team-invite-modal,
.modal {
  position: relative;
  width: 100%;
  max-width: 472px;
  max-height: calc(100vh - 48px);
  overflow: hidden auto;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: 0 28px 64px -20px rgba(0, 0, 0, .55);
  animation: modalIn .26s var(--ease);
}
.lfw-modal.is-wide { max-width: 720px; }

.lfw-modal-head,
.modal-head,
.hs-upload-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 20px 20px 16px;
}
.lfw-modal-head .t { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 6px; }
.lfw-modal-head h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: -.01em;
}
.lfw-modal-head p {
  margin: 0;
  color: var(--muted-2);
  font-size: 12.5px;
  line-height: 1.5;
  text-wrap: pretty;
}

.lfw-modal-close,
.hs-modal-close,
.team-modal-close {
  display: flex;
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted-2);
  cursor: pointer;
}
.lfw-modal-close:hover,
.hs-modal-close:hover,
.team-modal-close:hover { background: var(--btn-ghost-hover); color: var(--ink); }
.lfw-modal-close svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}

.lfw-modal-body,
.modal-body,
.hs-upload-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 18px 20px 20px;
}

.lfw-modal-foot,
.modal-foot,
.hs-upload-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  border-top: 1px solid var(--line-mid);
  background: var(--card-alt);
  flex-wrap: wrap;
}
.lfw-modal-foot .lfw-push { flex: 1; }
.lfw-modal-foot .btn { height: 36px; }

/* File drop target inside the modal. Replaces the raw browser
   "Choose File / No file chosen" control. */
.lfw-filedrop {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border: 1.5px dashed var(--dash);
  border-radius: 10px;
  background: var(--dz-bg);
  cursor: pointer;
  transition: transform .16s ease, background-color .24s ease, border-color .24s ease;
}
.lfw-filedrop:hover,
.lfw-filedrop.is-dragging { border-color: var(--dash-hover); background: var(--dz-hover); transform: translateY(-1px); }
.lfw-filedrop .ic {
  display: flex;
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent-soft);
}
.lfw-filedrop .ic svg {
  width: 15px;
  height: 15px;
  color: var(--accent);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.lfw-filedrop .t { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 2px; }
.lfw-filedrop .t b { color: var(--ink); font-size: 13px; font-weight: 500; }
.lfw-filedrop .t span { color: var(--muted-2); font-size: 11.5px; }
.lfw-filedrop input[type="file"] { display: none; }

.lfw-filechip {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 11px 11px 13px;
  border: 1px solid var(--line-mid);
  border-radius: 10px;
  background: var(--card-alt);
}
.lfw-filechip > svg {
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  color: var(--accent);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.lfw-filechip .t { display: flex; flex: 1; min-width: 0; flex-direction: column; gap: 1px; }
.lfw-filechip .t b {
  overflow: hidden;
  color: var(--ink);
  font-size: 13px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lfw-filechip .t span { color: var(--faint); font-size: 11.5px; }
.lfw-filechip .lfw-x { width: 24px; height: 24px; flex-basis: 24px; border-radius: 7px; }

/* ==========================================================================
   14. Members, list rows
   ========================================================================== */

.lfw-member {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 20px;
  border-top: 1px solid var(--line-mid);
  flex-wrap: wrap;
}
.lfw-member:hover { background: var(--row-hover); }

.tm-av,
.lfw-avatar-lg {
  display: flex;
  width: 34px;
  height: 34px;
  flex: 0 0 34px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--avatar-bg);
  color: var(--avatar-fg);
  font-size: 12.5px;
  font-weight: 600;
}

.tm-person { display: flex; flex: 1; min-width: 160px; flex-direction: column; gap: 2px; }
.tm-person .n { display: flex; align-items: center; gap: 7px; }
.tm-person .n b { color: var(--ink); font-size: 13.5px; font-weight: 500; }
/* A description that follows its label sits on its own line. The 2026-07-31
   restyle brought the colour and size of these across from console.css but not
   the `display`, so the two ran together as one word (QA 2026-08-26, F-06/F-07:
   "Dan Gregorydantgregory@outlook.com", "Reconstructed Word fileReview copy
   can be downloaded until..."). Same shape, so one rule per surface. */
.tm-email { display: block; margin-top: 2px; color: var(--faint); font-size: 12px; }
.demo-table td > small { display: block; margin-top: 2px; color: var(--muted-2); font-size: 11.5px; }

.lfw-member-role { flex: 0 0 auto; width: 90px; color: var(--ink-3); font-size: 13px; }

/* ==========================================================================
   15. Banners and inline messages
   ========================================================================== */

.banner,
.inline-message,
.api-message,
.api-msg,
.team-message,
.hs-status-line {
  padding: 12px 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card-alt);
  color: var(--ink-2);
  font-size: 12.5px;
  line-height: 1.5;
}
.banner.info, .inline-message.info { border-color: var(--accent-soft); background: var(--accent-soft); color: var(--accent-ink); }
.banner.success, .inline-message.is-success, .inline-message.success { border-color: var(--ok-bg); background: var(--ok-bg); color: var(--ok-fg); }
.banner.warn, .inline-message.warn { border-color: var(--warn-bg); background: var(--warn-bg); color: var(--warn-fg); }
.banner.error, .inline-message.is-error, .inline-message.error, .api-message.error { border-color: var(--fail-bg); background: var(--fail-bg); color: var(--fail-fg); }

/* ==========================================================================
   16. Auth gate
   ========================================================================== */

body.auth-pending .shell { visibility: hidden; }

.auth-gate {
  display: flex;
  position: fixed;
  z-index: 80;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: var(--bg);
  color: var(--muted);
  font-size: 13px;
  inset: 0;
}
body:not(.auth-pending) .auth-gate { display: none; }

.convert-spinner {
  display: block;
  width: 15px;
  height: 15px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}

/* ==========================================================================
   17. Section tabs
   ========================================================================== */

.section-tabs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.section-tab {
  display: inline-flex;
  height: 30px;
  align-items: center;
  padding: 0 13px;
  border: 1px solid var(--line);
  border-radius: 20px;
  color: var(--ink-3);
  font-size: 12.5px;
  font-weight: 500;
  text-decoration: none;
}
.section-tab:hover { border-color: var(--focus); color: var(--ink-3); text-decoration: none; }
.section-tab.is-active,
.section-tab[aria-current="page"] {
  border-color: var(--btn-bg);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-weight: 600;
}

/* ==========================================================================
   18. Workspace switcher menu (rendered by auth.js)
   ========================================================================== */

.ws-menu {
  display: flex;
  position: absolute;
  z-index: 40;
  left: 16px;
  width: 218px;
  flex-direction: column;
  gap: 2px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .45);
}
.ws-menu-heading,
.ws-menu-heading-account {
  padding: 6px 8px 4px;
  color: var(--muted-2);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.ws-menu-item,
.ws-menu-account,
.ws-menu-create,
.ws-menu-signout {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 8px;
  padding: 8px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  text-align: left;
  text-decoration: none;
}
.ws-menu-item:hover,
.ws-menu-account:hover,
.ws-menu-create:hover,
.ws-menu-signout:hover { background: var(--nav-hover); color: var(--ink); text-decoration: none; }
.ws-menu-check { color: var(--accent); }
.ws-menu-note { padding: 8px; color: var(--faint); font-size: 12px; }

/* ==========================================================================
   19. Legacy vocabulary — kept on-token so nothing renders unstyled
   ========================================================================== */

.demo-eyebrow {
  margin: 0;
  color: var(--muted-2);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.tbl-wrap { overflow-x: auto; }

.tbl,
.demo-table,
.job-detail-table,
.team-table,
.style-guide-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.tbl th,
.demo-table th,
.job-detail-table th,
.team-table th,
.style-guide-table th {
  padding: 9px 20px;
  border-top: 1px solid var(--line-mid);
  border-bottom: 1px solid var(--line-mid);
  background: var(--thead);
  color: var(--muted-2);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .1em;
  text-align: left;
  text-transform: uppercase;
}
.tbl td,
.demo-table td,
.job-detail-table td,
.team-table td,
.style-guide-table td {
  padding: 12px 20px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink-3);
  vertical-align: middle;
}
.tbl tbody tr:hover,
.demo-table tbody tr:hover { background: var(--row-hover); }
.tbl .num,
.demo-table .num { font-variant-numeric: tabular-nums; text-align: right; }

.empty-cell,
.table-empty,
.team-empty-cell,
.style-vault-empty,
.rule-review-empty,
.current-jobs-empty {
  padding: 34px 20px;
  color: var(--faint);
  font-size: 13px;
  text-align: center;
}

.mono { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 12px; }

.meta,
.sub,
.hint { color: var(--muted-2); font-size: 12.5px; }

.visually-hidden {
  position: absolute;
  overflow: hidden;
  width: 1px;
  height: 1px;
  padding: 0;
  border: 0;
  margin: -1px;
  clip-path: inset(50%);
  white-space: nowrap;
}

.lfw-push { flex: 1; }

.job-stat-grid,
.result-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 14px;
}

.job-stat,
.billing-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 15px 17px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--card);
  box-shadow: var(--card-shadow);
}
.job-stat-label,
.billing-stat .l {
  color: var(--muted-2);
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.job-stat-value,
.billing-stat .v {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 26px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.01em;
}

/* ==========================================================================
   20. Cookie consent
   site.js appends this banner to <body> on every page. The workspace shell is
   a bounded frame, so it must be position:fixed — left in normal flow it adds
   document height and makes the whole page scroll behind the pinned chrome.
   ========================================================================== */

.cookie-consent {
  display: flex;
  position: fixed;
  z-index: 70;
  bottom: 20px;
  left: 50%;
  width: min(720px, calc(100% - 40px));
  align-items: flex-end;
  gap: 18px;
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: 0 28px 64px -20px rgba(0, 0, 0, .45);
  transform: translateX(-50%);
  flex-wrap: wrap;
}

.cookie-consent-copy { flex: 1; min-width: 240px; }
.cookie-consent-copy h2 {
  margin: 0 0 6px;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -.01em;
}
.cookie-consent-copy p { margin: 0; color: var(--muted); font-size: 12.5px; line-height: 1.5; }

.cookie-consent-actions { display: flex; flex: 0 0 auto; gap: 10px; }

.cookie-button {
  height: 34px;
  padding: 0 14px;
  border: 1px solid var(--btn-line);
  border-radius: 9px;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
}
.cookie-button:hover { background: var(--btn-ghost-hover); }
.cookie-button-dark { border-color: var(--btn-bg); background: var(--btn-bg); color: var(--btn-fg); }
.cookie-button-dark:hover { background: var(--btn-hover); }

/* ==========================================================================
   22. Page vocabulary
   The pages carry a large inherited class vocabulary that the old per-page
   stylesheets owned. Those sheets are no longer loaded, so every one of these
   is restyled here on the same tokens — nothing is left to render unstyled.
   ========================================================================== */

/* --- Shared primitives ---------------------------------------------------- */

.raised { box-shadow: var(--card-shadow); }
.mt-20 { margin-top: 20px; }
.mt-22 { margin-top: 22px; }
.panel-body { display: flex; flex-direction: column; gap: 14px; padding: 18px 20px; }
.panel-actions,
.row-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.sec-head,
.hs-section-head,
.style-vault-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.sec-head h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -.01em;
}

.demo-view-actions,
.job-view-actions,
.team-panel-actions,
.hs-template-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.ct { color: var(--muted-2); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.dh, .dl { color: var(--faint); font-size: 12px; }
.arr { margin-left: 2px; }

.demo-info,
.report-privacy-note,
.notice-state {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--card-alt);
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.55;
}
.demo-info strong,
.notice-state strong,
.notice-state h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 16px;
  font-weight: 500;
}
.demo-info p, .notice-state p, .report-privacy-note p { margin: 0; }

.demo-settings-list { display: flex; flex-direction: column; margin: 0; }
.demo-settings-list > div {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: 12.5px;
}
.demo-settings-list > div:last-child { border-bottom: 0; }
.demo-settings-list dt { margin: 0; color: var(--muted); }
.demo-settings-list dd { margin: 0; color: var(--ink); font-weight: 500; text-align: right; }

.empty,
.hs-empty,
.style-vault-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 34px 20px;
  color: var(--faint);
  font-size: 13px;
  text-align: center;
}
.empty strong { color: var(--ink); font-family: var(--serif); font-size: 16px; font-weight: 500; }
.empty p { max-width: 460px; margin: 0; line-height: 1.55; }
.empty-icon, .empty .ic {
  display: flex;
  width: 38px;
  height: 38px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 17px;
}

.track, .proc-bar .bar, .demo-progress, .billing-usage-meter, .row-track {
  height: 4px;
  overflow: hidden;
  border-radius: 4px;
  background: var(--track);
}
/* Width 0 by default: an unhydrated bar must not read as "100% used". The page
   script sets the real width once the summary arrives. */
.track-fill, .proc-bar-fill, .demo-progress > i, .demo-progress > span, .billing-usage-meter > i {
  display: block;
  width: 0;
  height: 100%;
  border-radius: 4px;
  background: var(--accent);
  transform-origin: left;
}
.usage-meter-label { color: var(--faint); font-size: 11.5px; }

.ring {
  display: inline-block;
  width: 13px;
  height: 13px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin .7s linear infinite;
}

.pipe, .job-pipe { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pstep {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted-2);
  font-size: 12px;
}
.pstep.done { color: var(--ok-fg); }
.pstep.running { color: var(--proc-fg); }

.st, .file-status { color: var(--muted-2); font-size: 12.5px; }
.amber { color: var(--warn-fg); }
.done { color: var(--ok-fg); }

.errcard, .flat-error, .reconstruct-error, .error-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 18px;
  border: 1px solid var(--fail-bg);
  border-radius: 14px;
  background: var(--fail-bg);
  color: var(--fail-fg);
  font-size: 12.5px;
  line-height: 1.55;
}

.info-glyph {
  display: inline-flex;
  width: 15px;
  height: 15px;
  flex: 0 0 15px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: 10px;
  font-weight: 600;
}

.allowance-nudge { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.allowance-nudge-actions { display: flex; gap: 8px; margin-left: auto; }

/* --- Reconstructions ------------------------------------------------------ */

.hero,
.reconstruct-stage,
.reconstruct-panel,
.overview-upload-card,
.overview-quality-panel,
.current-jobs,
.job-summary-panel,
.job-processing-panel,
.job-download-panel,
.job-metadata-panel,
.account-identity,
.account-profile-panel,
.account-alerts-panel,
.account-membership-panel,
.billing-section,
.billing-cycle,
.style-vault-panel {
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: var(--card-shadow);
}

.reconstruct-panel, .overview-upload-card { padding: 18px 20px; }
.reconstruct-upload-stack, .overview-upload-details { display: flex; flex-direction: column; gap: 12px; }
.reconstruct-body,
.reconstruct-processing,
.reconstruct-result,
.job-summary-body,
.job-processing-body,
.billing-cycle-body {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px 20px;
}

/* The upload control is the prototype's inline bar. The old 260px panel, its
   "No file selected" line and the separate footnote strip below it are gone. */
.drop,
.convert-drop,
.overview-dropzone,
.demo-dropzone,
.hs-upload-drop {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 16px 20px;
  border: 1.5px dashed var(--dash);
  border-radius: 14px;
  background: var(--dz-bg);
  cursor: pointer;
  flex-wrap: wrap;
  transition: transform .18s ease, background-color .24s ease, border-color .24s ease;
}
.drop:hover, .convert-drop:hover, .overview-dropzone:hover, .demo-dropzone:hover, .hs-upload-drop:hover,
.drop.is-dragging, .convert-drop.is-dragging, .overview-dropzone.is-dragging {
  border-color: var(--dash-hover);
  background: var(--dz-hover);
  transform: translateY(-2px);
}

.demo-drop-icon,
.overview-upload-badge {
  display: flex;
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
}
.demo-drop-icon svg, .overview-upload-badge svg { width: 17px; height: 17px; }

/* The Reconstructions dropzone's children are flat siblings, so the bar's
   shape — icon left, title over its sub-line, constraints right — is laid out
   on a grid rather than by wrapping the markup (which convert.js owns). */
.convert-drop {
  display: grid;
  align-items: center;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  grid-template-areas:
    "icon title hint"
    "icon copy  status";
  column-gap: 14px;
  row-gap: 2px;
}
.convert-drop .demo-drop-icon, .convert-drop .overview-upload-badge { grid-area: icon; }
.convert-drop [data-drop-title] {
  grid-area: title;
  color: var(--ink);
  font-size: 14.5px;
  font-weight: 500;
}
.convert-drop .overview-drop-copy { grid-area: copy; }
.convert-drop .dh { grid-area: hint; text-align: right; }
.convert-drop .file-status { grid-area: status; text-align: right; }

.overview-drop-copy, .drop-copy {
  display: block;
  min-width: 0;
  color: var(--muted-2);
  font-size: 12.5px;
  font-weight: 400;
}
.overview-drop-copy small, .drop-copy small { color: var(--muted-2); font-size: 12.5px; }

/* Status strips that JS leaves in the DOM but empty must not draw a box. */
.banner:empty,
.inline-message:empty,
.api-message:empty,
.api-msg:empty,
.team-message:empty,
.hs-status-line:empty,
.notice-state:empty,
.errcard:empty { display: none; }

.browse-link {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.overview-scan-note {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  margin: 0;
  color: var(--muted-2);
  font-size: 12px;
  line-height: 1.45;
}

.overview-reveal, .current-jobs { display: flex; flex-direction: column; gap: 14px; }
.current-jobs-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 16px 20px 15px;
  flex-wrap: wrap;
}
.current-jobs-state, .current-jobs-message { color: var(--faint); font-size: 12px; }
.current-jobs-link { font-size: 13px; font-weight: 500; }

/* The select and the "House styles" link share a row; the message spans beneath.
   The 2026-07-31 restyle collapsed this to a plain column, which stranded the link
   on its own line at full size. Its colour came from --muted-strong, a console.css
   token that does not exist here, so the declaration was dropped rather than
   translated and the link fell through to the bare `a` rule — accent gold. */
.style-picker {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px 14px;
  align-items: end;
}
.style-confirm, .template-message { grid-column: 1 / -1; }
.style-manage-link { align-self: center; color: var(--muted-2); white-space: nowrap; }
.style-manage-link:hover { color: var(--ink-3); }

.style-confirm {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  border: 1px solid var(--line-mid);
  border-radius: 12px;
  background: var(--card-alt);
}
/* Lost display:flex in the same pass, so the name, the self-test note and the
   change button ran together as one sentence with no spacing. */
.style-confirm-line {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: var(--ink-2);
  font-size: 13px;
  flex-wrap: wrap;
}
.style-confirm-selftest,
.style-sheet-hint,
.hs-optional,
.hs-upload-note,
.hs-notes-help { color: var(--faint); font-size: 11.5px; }
.style-manage-link, .style-sheet-manage { font-size: 12.5px; font-weight: 500; }

.trust { display: flex; gap: 18px; color: var(--muted-2); font-size: 12px; flex-wrap: wrap; }
.hero-cta, .conversion-mode-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* The label swaps to "Checking..." / "Uploading..." while a submit runs, which is a
   narrower word than "Reconstruct". Pin the resting width so the button the user just
   clicked does not shrink under the cursor. */
[data-convert-action] { min-width: 8.5rem; justify-content: center; }
.hero-form { display: flex; flex-direction: column; gap: 12px; }
.batch-file-list { display: flex; flex-direction: column; gap: 8px; }
.batch-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line-mid);
  border-radius: 10px;
  background: var(--card-alt);
  font-size: 12.5px;
}

.result-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 14px;
}
.result-actions, .result-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.result-foot { color: var(--faint); font-size: 12px; }
.processing-detail, .proc-meta, .job-processing-note { color: var(--faint); font-size: 12px; }
.proc-file { color: var(--ink); font-size: 13.5px; font-weight: 500; }
.flag-section, .hs-result-lines, .report-preview { display: flex; flex-direction: column; gap: 8px; }
.report-doc { color: var(--ink); font-size: 13.5px; font-weight: 500; }
.conv-hidden-extra { display: flex; flex-direction: column; gap: 14px; }

/* Style-sheet picker modal on the Reconstructions page. */
.style-sheet-backdrop {
  display: flex;
  position: fixed;
  z-index: 60;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(18, 14, 10, .58);
  backdrop-filter: blur(2px);
  inset: 0;
}
.style-sheet-modal {
  width: 100%;
  max-width: 472px;
  max-height: calc(100vh - 48px);
  overflow: hidden auto;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: 0 28px 64px -20px rgba(0, 0, 0, .55);
}
.style-sheet-head, .sheet-head { padding: 20px 20px 16px; }
.style-sheet-head h2, .sheet-head h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: -.01em;
}
.style-sheet-body, .sheet-body, .hs-upload-body, .team-invite-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 18px 20px 20px;
  border-top: 1px solid var(--line-mid);
}
.style-sheet-foot, .sheet-foot, .team-invite-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  border-top: 1px solid var(--line-mid);
  background: var(--card-alt);
  flex-wrap: wrap;
}
.style-sheet-foot .btn:last-child, .team-invite-foot .btn:last-child { margin-left: auto; }
.hs-file-label { cursor: pointer; }
/* .style-sheet-file used to be hidden here too, but the modal never got the
   visible label that pattern needs, so the only affordance was a heading that
   looked exactly like the non-clickable one above it (QA 2026-08-26, F-02).
   The field is now an .lfw-filedrop, which hides its own input. */
.style-sheet-file-label { display: block; margin-top: 18px; }
.style-sheet-drop { margin-top: 6px; }
.style-sheet-drop.has-file { border-style: solid; border-color: var(--accent); background: var(--accent-soft); }
.file-input-hidden { position: absolute; width: 1px; height: 1px; opacity: 0; }

/* --- Document detail ------------------------------------------------------ */

.job-view-head { align-items: flex-start; }
/* The way out of a document that cannot be shown (QA 2026-08-26, F-08). */
.job-unavailable-actions { margin: 14px 0 0; }
.job-summary-copy { color: var(--muted); font-size: 13px; line-height: 1.55; }
.job-meta-privacy { color: var(--faint); font-size: 11.5px; }
/* Six labelled values, not one sentence — console.css laid these out as a
   wrapping flex row and the restyle kept only the colour and size, so they
   rendered as "Status: Needs review Submitted: ..." (QA 2026-08-26, F-22). */
.job-meta-line {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  color: var(--faint);
  font-size: 11.5px;
}
.job-file-type { color: var(--ink-3); font-size: 12.5px; }

/* Keep the live processing state compact and readable. The outer .proc-bar
   contains labels, so only its inner .bar may behave like a clipped track. */
.job-processing-panel .lfw-card-head {
  align-items: flex-start;
  justify-content: space-between;
}
.job-processing-panel .lfw-card-head > div:first-child {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 4px;
}
.job-processing-panel .lfw-card-head p { margin: 0; color: var(--muted-2); font-size: 12.5px; }
.job-processing-body {
  gap: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
}
.job-processing-note {
  max-width: 900px;
  margin: 0;
  line-height: 1.5;
}
.job-processing-panel .job-pipe {
  display: grid;
  position: relative;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
  padding: 2px 0;
}
.job-processing-panel .job-pipe .track,
.job-processing-panel .job-pipe .track-fill {
  position: absolute;
  z-index: 0;
  top: 18px;
  right: 12.5%;
  left: 12.5%;
  width: auto;
  height: 2px;
}
.job-processing-panel .job-pipe .track-fill.is-rebuild { right: 50%; }
.job-processing-panel .pstep {
  display: grid;
  position: relative;
  z-index: 1;
  min-width: 0;
  justify-items: center;
  gap: 3px;
  text-align: center;
}
.job-processing-panel .pstep .ring {
  display: grid;
  width: 32px;
  height: 32px;
  margin-bottom: 3px;
  place-items: center;
  border-width: 1px;
  background: var(--card);
}
.job-processing-panel .pstep .ring svg { width: 15px; height: 15px; }
.job-processing-panel .pstep.done .ring,
.job-processing-panel .pstep.active .ring { border-color: var(--accent); color: var(--accent); }
.job-processing-panel .pstep .nm { color: var(--ink-2); font-size: 11.5px; font-weight: 500; }
.job-processing-panel .pstep .st { font-size: 10.5px; }
.job-processing-panel .proc-meta {
  display: grid;
  align-items: center;
  grid-template-columns: minmax(220px, .75fr) minmax(280px, 1.25fr);
  gap: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line-soft);
}
.job-processing-panel .proc-file {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 10px;
}
.job-processing-panel .proc-file > div:last-child { min-width: 0; }
.job-processing-panel .job-file-type {
  display: grid;
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  place-items: center;
  border: 1px solid var(--line-mid);
  border-radius: 9px;
  color: var(--accent);
  font-family: var(--mono);
  font-size: 10px;
}
.job-processing-panel .proc-file .nm {
  overflow: hidden;
  color: var(--ink);
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.job-processing-panel .proc-file .sub { margin-top: 3px; color: var(--muted-2); font-size: 11px; }
.job-processing-panel .proc-bar { min-width: 0; }
.job-processing-panel .proc-bar .lbl {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-top: 7px;
  color: var(--muted-2);
  font-size: 10.5px;
}

.job-hidden-timeline { display: flex; flex-direction: column; padding: 4px 20px 18px; }
.tl {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line-soft);
  font-size: 12.5px;
}
.tl:last-child { border-bottom: 0; }
.tl .nm { flex: 1; color: var(--ink-3); }
.tl .time { color: var(--faint); font-variant-numeric: tabular-nums; }
.tl.pending .nm { color: var(--faintest); }
.job-status-dot {
  width: 6px;
  height: 6px;
  flex: 0 0 6px;
  border-radius: 50%;
  background: var(--faintest);
}
.tl.done .job-status-dot { background: var(--ok-fg); }
.job-hidden-values { display: flex; flex-direction: column; gap: 6px; }
.job-download-table, .job-detail-table { width: 100%; }

/* --- Account -------------------------------------------------------------- */

/* Shared theme tokens keep the account summary readable in both modes. */
.account-identity-body { display: grid; grid-template-columns: 48px minmax(0, 1fr) minmax(175px, auto); align-items: center; gap: 16px; padding: 26px; }
.account-avatar {
  display: flex;
  width: 48px;
  height: 48px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--avatar-bg);
  color: var(--avatar-fg);
  font-size: 16px;
  font-weight: 500;
}
.account-identity-main { display: flex; min-width: 0; flex-direction: column; gap: 9px; }
.account-name-row h2 { margin: 0; font-size: 21px; overflow-wrap: anywhere; }
.account-email { display: flex; align-items: center; flex-wrap: wrap; gap: 7px 10px; margin: 0; color: var(--muted); font-size: 13px; }
#acct-email-display { min-width: 0; overflow-wrap: anywhere; }
.account-email-verified { display: inline-flex; align-items: center; gap: 4px; color: var(--ok-fg); font-size: 12px; white-space: nowrap; }
.account-email-verified svg { width: 14px; height: 14px; }
.account-facts { padding: 0; min-width: 0; gap: 10px; }
.account-facts > div { padding: 0; border: 0; gap: 24px; }
.account-facts dd { max-width: 240px; overflow-wrap: anywhere; }
.account-membership-list { padding: 4px 20px 18px; }
@media (max-width: 700px) {
  .account-identity-body { grid-template-columns: 48px minmax(0, 1fr); padding: 22px 18px; }
  .account-facts { grid-column: 1 / -1; padding-top: 20px; margin-top: 6px; border-top: 1px solid var(--line); }
  .account-facts dd { max-width: 65%; }
}
.account-copy-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 18px 20px;
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.55;
}
.account-copy-icon { color: var(--accent); }

/* --- Billing -------------------------------------------------------------- */

.billing-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; }
.billing-panels { display: grid; align-items: stretch; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 18px; }
.billing-catalog { display: flex; flex-direction: column; gap: 12px; padding: 4px 20px 18px; }
.billing-interval-toggle { display: flex; gap: 8px; padding-bottom: 4px; }
.billing-interval-toggle .btn[aria-pressed="true"] { pointer-events: none; }
.billing-payment-actions { display: flex; gap: 10px; padding: 4px 20px 18px; flex-wrap: wrap; }

/* --- Usage & quality ------------------------------------------------------ */

.cols { display: grid; gap: 18px; }
.cols-3a { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); }
.barstrip { display: flex; height: 120px; align-items: flex-end; gap: 6px; padding: 18px 20px; }
.barstrip > * { flex: 1; border-radius: 3px 3px 0 0; background: var(--accent-soft); }
.donut-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  padding: 18px 20px;
  flex-wrap: wrap;
}
/* Both circles are stroked arcs, not filled discs — without fill:none the
   <circle> paints as a solid black blob. reports.js sets the dash offset. */
.donut-ring {
  width: 140px;
  height: 140px;
  flex: 0 0 140px;
  transform: rotate(-90deg);
}
.donut-ring circle {
  fill: none;
  stroke-width: 16;
  stroke-linecap: round;
}
.donut-bg { stroke: var(--track); }
.donut-pass { stroke: var(--accent); }
.donut-legend { display: flex; flex: 1; min-width: 180px; flex-direction: column; gap: 8px; padding: 0; }
.donut-legend .r b { margin-left: auto; color: var(--ink); font-variant-numeric: tabular-nums; }
.donut-legend .r { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12.5px; }
.sw { width: 9px; height: 9px; flex: 0 0 9px; border-radius: 3px; background: var(--track); }
.key-pass { background: var(--ok-fg); }
.key-review { background: var(--warn-fg); }
.key-fail { background: var(--fail-fg); }
.exports { display: flex; gap: 8px; flex-wrap: wrap; }

/* --- House styles --------------------------------------------------------- */

.demo-style-grid { display: grid; align-items: stretch; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: 18px; }
.style-vault-list { display: flex; flex-direction: column; gap: 12px; padding: 18px 20px; }
.style-vault-template-select { height: 34px; padding: 0 10px; font-size: 12.5px; }
.actions-head { text-align: right; }
.hs-upload-form { display: flex; flex-direction: column; }
.demo-text-field { display: flex; flex-direction: column; gap: 6px; }

/* --- Team ----------------------------------------------------------------- */

.team-panel-head { align-items: flex-start; }
.invite-row, .team-form-row { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
.invite-row .lfw-field, .team-form-row .lfw-field { flex: 1; min-width: 220px; }
.team-invite-head { display: flex; align-items: flex-start; gap: 12px; padding: 20px 20px 16px; }
.team-invite-head > div:first-child { flex: 1; min-width: 0; }
.team-invite-head h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: -.01em;
}
.team-invite-head p { margin: 0; color: var(--muted-2); font-size: 12.5px; }
.team-button { flex: 0 0 auto; }

/* --- Settings ------------------------------------------------------------- */

.settings-card { display: flex; flex-direction: column; gap: 14px; }
.settings-help { margin: 0; }
.switch { position: absolute; width: 1px; height: 1px; opacity: 0; }

/* --- Documents list ------------------------------------------------------- */

.jobs-table-panel .panel-head .find {
  display: flex;
  width: 260px;
  max-width: 100%;
  height: 34px;
  align-items: center;
  gap: 9px;
  margin-left: auto;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--input-bg);
}
.jobs-table-panel .panel-head .find:focus-within { border-color: var(--focus); }
.jobs-table-panel .panel-head .find svg { width: 14px; height: 14px; flex: 0 0 14px; color: var(--muted-2); }
.jobs-table-panel .panel-head .find input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-size: 13px;
  outline: none;
}
.jobs-doc-meta { color: var(--faint); font-size: 11.5px; }
.jobs-pages-cell, .jobs-submitted-cell { font-variant-numeric: tabular-nums; }
.jobs-action-cell, .jobs-table .actions-head { text-align: right; }
.rowchev { color: var(--faintest); }
.col-sec { color: var(--faint); font-size: 11.5px; }
.clickrow { cursor: pointer; }
.status-stack { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.batch-toggle {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
}

/* --- Remaining page hooks -------------------------------------------------- */

.acts, .row-actions.acts { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.cell { min-width: 0; }
.rrow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rt { color: var(--ink-3); font-size: 13px; }
.why { color: var(--faint); font-size: 11.5px; }

.error-message, .error-support { color: inherit; font-size: 12.5px; }
.template-message { margin: 0; }

.overview-documents, .overview-verification-summary { display: flex; flex-direction: column; gap: 14px; }
.overview-jobs-table, .jobs-table-panel, .job-hidden-section { overflow: hidden; }

.filter { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.field-stack { display: flex; flex-direction: column; gap: 6px; }
.invite-hint { margin: 0; color: var(--faint); font-size: 11.5px; line-height: 1.5; }
.team-invitation-table { width: 100%; }

.settings-workspace, .settings-card-grid { width: 100%; }
.settings-field { display: block; }
.settings-workspace-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 18px;
  padding: 4px 20px 20px;
}
.settings-workspace-foot { justify-content: flex-end; }
.settings-retention-options { align-self: flex-start; }

.account-trust { margin-top: 0; }

.demo-status-done { background: var(--ok-bg); color: var(--ok-fg); }
.demo-status-new { background: var(--accent-soft); color: var(--accent-ink); }

/* --- Classes emitted by page scripts --------------------------------------
   These never appear in the static HTML, so they are easy to miss when the
   per-page stylesheets are retired. Same tokens, same shapes. */

.house-style-rules-list { display: flex; flex-direction: column; gap: 8px; }
.house-style-notes,
.house-style-notes-footer { display: flex; flex-direction: column; gap: 6px; }
.house-style-notes-label {
  color: var(--muted-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.house-style-notes-counter,
.house-style-notes-status { color: var(--faint); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.house-style-notes-field {
  height: 34px;
  padding: 0 11px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--input-bg);
  color: var(--ink);
  font-size: 13px;
  outline: none;
}
.house-style-notes-field:focus { border-color: var(--focus); }
.house-style-rule-examples { display: flex; flex-direction: column; gap: 4px; }
.house-style-rule-examples-label,
.house-style-rule-example { font-size: 11.5px; }
.style-name-clamp { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hs-action-slot, .hs-actions-cell { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.hs-edit-fields { display: flex; flex-direction: column; gap: 10px; }
.hs-edit-error { color: var(--fail-fg); font-size: 12px; }

/* Rule review, style guide and style catalogue sheets. */
.rule-review-list,
.style-guide-exemplar-list,
.style-catalog-list,
.style-vault-list { display: flex; flex-direction: column; gap: 8px; }

.rule-review-row,
.style-guide-exemplar-row,
.style-catalog-row,
.style-guide-card,
.discovery-row,
.plan-row,
.batch-file-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  border: 1px solid var(--line-mid);
  border-radius: 10px;
  background: var(--card-alt);
  font-size: 12.5px;
  flex-wrap: wrap;
}
.plan-row.current, .style-catalog-row.cur { border-color: var(--accent-line, var(--focus)); }

.rule-label,
.style-catalog-type,
.style-guide-family,
.discovery-status,
.lab { color: var(--muted); font-size: 12px; }
.rule-value, .val, .style-catalog-current-role { color: var(--ink-2); font-size: 12.5px; }
.rule-state, .style-catalog-status, .style-tier, .selftest {
  padding: 2px 8px;
  border-radius: 20px;
  background: var(--chip-bg);
  color: var(--chip-fg);
  font-size: 11px;
  font-weight: 600;
}
/* Scoped to the pill-shaped elements. `.green` / `.amber` are also added to bare
   metric VALUES by setMetricTone, where a background paints the whole tile. */
.rule-state.green, .style-catalog-status.green, .style-tier.green, .selftest.green,
.style-catalog-status-approved, .applied { background: var(--ok-bg); color: var(--ok-fg); }
.rule-state.suggested, .style-catalog-status.suggested, .style-tier.suggested,
.style-catalog-status-suggested { background: var(--warn-bg); color: var(--warn-fg); }
.green { color: var(--ok-fg); }
.amber { color: var(--warn-fg); }

.style-guide-grid, .style-catalog-group { display: flex; flex-direction: column; gap: 12px; }
.style-guide-head, .selftest-diagnostics-head, .style-catalog-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.style-guide-table-wrap { overflow-x: auto; }
.style-guide-conventions, .style-guide-exemplars, .style-catalog-body { display: flex; flex-direction: column; gap: 10px; }
.style-guide-exemplar-actions, .style-catalog-actions { display: flex; gap: 8px; margin-left: auto; }
.style-guide-upload, .style-catalog-specimen { color: var(--faint); font-size: 11.5px; }
.style-catalog-metadata, .style-catalog-formatting-summary, .style-catalog-suggestion { color: var(--muted-2); font-size: 12px; }
.style-catalog-human-choice { color: var(--accent-ink); font-size: 12px; font-weight: 500; }

.hs-rules-modal, .hs-edit-modal, .style-catalog-modal {
  width: 100%;
  max-width: 560px;
  max-height: calc(100vh - 48px);
  overflow: hidden auto;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
  box-shadow: 0 28px 64px -20px rgba(0, 0, 0, .55);
}
.hs-rules-modal.wide, .style-catalog-modal.wide { max-width: 760px; }
body.hs-modal-open { overflow: hidden; }

/* Notifications menu. */
.notify-wrap { position: relative; }
.notify-btn {
  display: flex;
  width: 32px;
  height: 32px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--btn-line);
  border-radius: 9px;
  background: transparent;
  color: var(--ink-3);
  cursor: pointer;
}
.notify-btn:hover { background: var(--btn-ghost-hover); }
.notify-btn.has-new::after {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  content: "";
}
.notify-menu {
  display: flex;
  position: absolute;
  z-index: 40;
  top: calc(100% + 8px);
  right: 0;
  width: 320px;
  max-height: 60vh;
  flex-direction: column;
  overflow: hidden auto;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .45);
}
.notify-item-top, .notify-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.notify-meta { color: var(--faint); font-size: 11.5px; }
.notify-empty { padding: 18px 10px; color: var(--faint); font-size: 12.5px; text-align: center; }

/* Row transitions used by the live-updating tables. */
.row-enter { animation: rowIn .32s var(--ease) both; }
.row-done-flash { animation: fadeIn .4s ease; }
.is-leaving { opacity: .5; }
.is-decorative { pointer-events: none; }

.flagchip {
  padding: 2px 8px;
  border-radius: 20px;
  background: var(--warn-bg);
  color: var(--warn-fg);
  font-size: 11px;
  font-weight: 600;
}
.overview-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 9px 3px 8px;
  border-radius: 20px;
  background: var(--flat-bg);
  color: var(--flat-fg);
  font-size: 11.5px;
  font-weight: 600;
}
.wording-cell, .nm-cell, .doc { min-width: 0; }
.learned-count, .created, .price, .feat { color: var(--muted-2); font-size: 12.5px; }
.style-catalog-group > .lab { font-weight: 600; }
.team-admin-only { display: contents; }
.current-jobs-state { color: var(--faint); font-size: 12px; }
.current-job-download { margin-left: auto; }
.empty-line { color: var(--faintest); }
.badge {
  padding: 2px 8px;
  border-radius: 20px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: 11px;
  font-weight: 600;
}
.del { color: var(--danger-body); }
.del:hover { color: var(--fail-fg); }
.edit { color: var(--accent); }

.col { min-width: 0; }
.style-guide-coverage { color: var(--muted-2); font-size: 12px; font-variant-numeric: tabular-nums; }

/* Sub-headings inside the JS-rendered cards. Guarded by live-qa-regressions:
   these are semantic h3/h4 elements and must not lose their styling. */
.house-style-card h3,
.style-guide-head h3 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 500;
  letter-spacing: -.01em;
}
.style-guide-table-wrap h4,
.style-guide-conventions h4,
.style-guide-exemplars h4 {
  margin: 0;
  color: var(--muted-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.jobs-table-panel .panel-head h2 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -.01em;
}

@media (prefers-reduced-transparency: reduce) {
  .lfw-modal-backdrop,
  .style-sheet-backdrop,
  .scrim,
  .hs-upload-scrim,
  .team-invite-backdrop { backdrop-filter: none; }
}

/* ==========================================================================
   23. Polish pass (2026-07-31, from live review)
   ========================================================================== */

/* An <svg> with a viewBox but no width/height fills its container. Component
   rules size the icons they know about; this is the backstop for every icon
   they do not, after one rendered a tick the height of the page. */
.shell svg { width: 16px; height: 16px; flex: 0 0 auto; }
.shell svg[width], .shell svg[height] { width: auto; height: auto; }
.shell .donut-ring { width: 140px; height: 140px; flex-basis: 140px; }

/* --- Recent reconstructions table ---------------------------------------
   The demo's Reconstructions table is a five-track grid. This is a real <table>
   that convert.js owns, so the same proportions are imposed with a fixed
   layout instead of rewriting the renderer's element types. */
.overview-jobs-table {
  min-width: 860px;
  table-layout: fixed;
}
.overview-jobs-table th:nth-child(1), .overview-jobs-table td:nth-child(1) { width: auto; }
.overview-jobs-table th:nth-child(2), .overview-jobs-table td:nth-child(2) { width: 72px; text-align: right; }
.overview-jobs-table th:nth-child(3), .overview-jobs-table td:nth-child(3) { width: 150px; }
.overview-jobs-table th:nth-child(4), .overview-jobs-table td:nth-child(4) { width: 190px; }
.overview-jobs-table th:nth-child(5), .overview-jobs-table td:nth-child(5) { width: 168px; text-align: right; }

.overview-jobs-table td { vertical-align: middle; }
.overview-jobs-table td:nth-child(1) { min-width: 0; }
.overview-jobs-table td:nth-child(1) .lnk {
  display: block;
  overflow: hidden;
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.overview-jobs-table td:nth-child(1) .lnk:hover { color: var(--accent); }
.overview-jobs-table td:nth-child(2) { font-variant-numeric: tabular-nums; }
.overview-jobs-table td:nth-child(3) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* The row's action is deliberately quiet. Solid buttons on every row formed a
   heavy column that outweighed the page's own primary call to action. */
.current-job-download {
  height: 30px;
  white-space: nowrap;
  padding: 0 11px;
  border: 1px solid var(--btn-line);
  border-radius: 8px;
  background: transparent;
  color: var(--ink-2);
  font-size: 12.5px;
  font-weight: 500;
}
.current-job-download:hover { background: var(--btn-ghost-hover); color: var(--ink-2); transform: none; }
.is-failed .current-job-download { border-color: var(--danger-btn-line); color: var(--fail-fg); }

/* Status pill takes its colour from the row's state, like every other table. */
.overview-status-pill { background: var(--flat-bg); color: var(--flat-fg); }
/* Every finished draft is labelled "Complete" (Dan, 2026-09-19), so review rows wear
   the same green as complete; only failed and cancelled rows look different. */
.is-complete .overview-status-pill,
.is-review .overview-status-pill { background: var(--ok-bg); color: var(--ok-fg); }
.is-processing .overview-status-pill,
.is-queued .overview-status-pill { background: var(--proc-bg); color: var(--proc-fg); }
.is-failed .overview-status-pill { background: var(--fail-bg); color: var(--fail-fg); }
.overview-jobs-table .row-track { width: 105px; margin-top: 6px; }
.current-job-stage-count {
  display: block;
  margin-top: 5px;
  color: var(--muted-2);
  font-size: 10px;
  line-height: 1.2;
  white-space: nowrap;
}
.overview-jobs-table .row-track i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--accent);
  transition: width 180ms var(--ease);
}

.current-job-meta {
  display: block;
  overflow: hidden;
  margin-top: 3px;
  color: var(--faint);
  font-size: 11.5px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- House style cards ---------------------------------------------------
   Cards stretch to a common height and pin their action row to the bottom, so
   two cards with different numbers of rules still line their footers up. */
.house-style-card { height: 100%; }

.house-style-badges { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.house-style-facts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 14px;
  font-size: 12.5px;
}
.house-style-facts .k { color: var(--faint); }
.house-style-facts .v {
  overflow: hidden;
  color: var(--ink-2);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.house-style-facts .v.is-empty { color: var(--faint); }

.house-style-notes { display: flex; flex-direction: column; gap: 8px; }
.house-style-notes-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}
.house-style-notes-label {
  color: var(--muted-2);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.house-style-notes-counter { color: var(--faint); font-size: 11.5px; font-variant-numeric: tabular-nums; }

.house-style-rules-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0;
  margin: 0;
  list-style: none;
}

/* Input and Add on ONE row. They used to stack with the counter orphaned
   between them, and Add was a full-width accent bar louder than the card. */
.house-style-rule-input { display: flex; gap: 8px; }
.house-style-rule-input input { flex: 1; min-width: 0; height: 34px; }
.house-style-rule-add {
  height: 34px;
  flex: 0 0 auto;
  padding: 0 13px;
  border: 1px solid var(--btn-line);
  border-radius: 9px;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  font: inherit;
  font-size: 12.5px;
  font-weight: 500;
}
.house-style-rule-add:hover:not(:disabled) { background: var(--btn-ghost-hover); }
.house-style-rule-add:disabled { border-color: var(--line); color: var(--faintest); cursor: default; }

/* Description panel: label, an editable note, and a Save button aligned with a save status. */
.house-style-description-panel { display: flex; flex-direction: column; gap: 8px; }
textarea.house-style-description-field { width: 100%; min-height: 54px; resize: vertical; }
.house-style-description-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.house-style-rule-remove {
  display: flex;
  width: 22px;
  height: 22px;
  flex: 0 0 22px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted-2);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
}
.house-style-rule-remove:hover { background: var(--btn-ghost-hover); color: var(--ink); }

/* One link, not three dumped example lines. */
.house-style-rule-examples { display: flex; flex-direction: column; gap: 4px; }
.house-style-rule-examples-toggle {
  align-self: flex-start;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  font-size: 11.5px;
  font-weight: 500;
}
.house-style-rule-examples-toggle:hover { text-decoration: underline; text-underline-offset: 2px; }
.house-style-rule-example {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--muted-2);
  cursor: pointer;
  font: inherit;
  font-size: 11.5px;
  text-align: left;
}
.house-style-rule-example:hover { color: var(--accent); }

.house-style-rules-empty {
  padding: 10px 11px;
  border: 1px dashed var(--line);
  border-radius: 9px;
  color: var(--faint);
  font-size: 12.5px;
}

/* Delete sits apart from the constructive actions rather than fourth in a row
   of equals. */
.house-style-actions { margin-top: auto; padding-top: 2px; flex-wrap: nowrap; }
.house-style-actions .spacer { flex: 1 1 0; min-width: 0; }
.house-style-actions .btn { flex: 0 0 auto; }
.house-style-actions .btn.quiet { padding: 0 4px; }
.house-style-actions .del { color: var(--danger-body); }
.house-style-actions .del:hover { color: var(--fail-fg); }

/* --- Live review round 2 -------------------------------------------------- */

.house-style-name-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}
.house-style-name-row .house-style-name { flex: 1; min-width: 0; }

.house-style-rename {
  display: flex;
  width: 28px;
  height: 28px;
  flex: 0 0 28px;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--btn-line);
  border-radius: 7px;
  background: transparent;
  color: var(--muted-2);
  cursor: pointer;
}
.house-style-rename:hover:not(:disabled) { background: var(--btn-ghost-hover); color: var(--ink); }
.house-style-rename:disabled { border-color: var(--line); color: var(--faintest); cursor: default; }
.house-style-rename svg { width: 14px; height: 14px; }

/* A metric VALUE is text, not a filled bar. setMetricTone adds a tone class,
   which was picking up the pill background and painting the whole tile width. */
.job-stat-value,
.billing-stat .v,
.stat .v,
.lfw-stat .v {
  display: block;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}
.job-stat-value.green, .job-stat-value.ok, .job-stat-value.is-ok { color: var(--ok-fg); }
.job-stat-value.amber, .job-stat-value.warn { color: var(--warn-fg); }
.job-stat-value.danger, .job-stat-value.error { color: var(--fail-fg); }

/* Change-report sections are appended straight into the card, so they carried
   no padding and sat outside its gutter. */
#job-change-report-sections {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 4px 20px 20px;
}
#job-change-report-sections h3,
#job-change-report-sections h4 {
  margin: 0;
  color: var(--ink);
  font-family: var(--serif);
  font-size: 15.5px;
  font-weight: 500;
  letter-spacing: -.01em;
}
#job-change-report-sections p {
  margin: 0;
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.55;
}
#job-change-report-sections > * + * { margin-top: 0; }

/* --- Billing ---------------------------------------------------------------
   Plan and pack rows are name-on-the-left, price-and-action-on-the-right. As a
   plain flex row everything bunched left with a third of the card empty. */

.plan-row {
  display: grid;
  align-items: center;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px 18px;
  padding: 14px 16px;
}
.plan-row .pi { display: flex; min-width: 0; flex-direction: column; gap: 3px; }
.plan-row .nm {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 500;
  flex-wrap: wrap;
}
.plan-row .feat { color: var(--muted-2); font-size: 12px; }
.plan-row .pr {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
}
.plan-row .price {
  color: var(--ink);
  font-family: var(--serif);
  font-size: 17px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.plan-row .price small { color: var(--muted-2); font-family: var(--sans); font-size: 11.5px; }
.plan-row .btn { flex: 0 0 auto; white-space: nowrap; }

/* The card head is a title block plus one trailing control, not three items
   competing for the same line. */
.billing-section .lfw-card-head,
.billing-cycle .lfw-card-head { align-items: flex-start; }
.billing-section .lfw-card-head > div:first-child,
.billing-cycle .lfw-card-head > div:first-child {
  display: flex;
  flex: 1;
  min-width: 0;
  flex-direction: column;
  gap: 3px;
}
.billing-section .lfw-card-head > .btn,
.billing-section .lfw-card-head > a.btn { margin-left: auto; }

/* Invoices: fixed tracks so the number stops wrapping, and both actions stay
   on one line instead of stacking in a narrow column. */
#billing-invoices-body { font-variant-numeric: tabular-nums; }
.billing-section .demo-table { table-layout: fixed; }
.billing-section .demo-table th:nth-child(1),
.billing-section .demo-table td:nth-child(1) { width: 34%; }
.billing-section .demo-table th:nth-child(2),
.billing-section .demo-table td:nth-child(2) { width: 16%; }
.billing-section .demo-table th:nth-child(3),
.billing-section .demo-table td:nth-child(3) { width: 14%; }
.billing-section .demo-table th:nth-child(4),
.billing-section .demo-table td:nth-child(4) { width: 16%; }
.billing-section .demo-table th:nth-child(5),
.billing-section .demo-table td:nth-child(5) { width: 20%; text-align: right; }

.billing-section .demo-table td.row-actions {
  display: table-cell;
  white-space: nowrap;
}
.billing-section .demo-table td.row-actions .btn { margin-left: 6px; }
.billing-section .demo-table td.row-actions .btn:first-child { margin-left: 0; }

/* --- Documents table ------------------------------------------------------
   The document cell holds a name line, a metadata line and a short id as
   inline spans, so they ran together as one wrapped sentence
   ("PDFAT lease signed.pdf12 pages review copy 881c555f"). */

/* Document · House style · Status · Wording check · Pages · Submitted · action */
/* Six columns since the 2026-08-31 History slim:
   Document | Status | Completed | Expires | Converted by | action. */
.jobs-table { table-layout: fixed; min-width: 900px; }
.jobs-table th:nth-child(1), .jobs-table td:nth-child(1) { width: auto; }
.jobs-table th:nth-child(2), .jobs-table td:nth-child(2) { width: 150px; }
.jobs-table th:nth-child(3), .jobs-table td:nth-child(3) { width: 132px; }
.jobs-table th:nth-child(4), .jobs-table td:nth-child(4) { width: 110px; }
.jobs-table th:nth-child(5), .jobs-table td:nth-child(5) { width: 190px; }
.jobs-table td:nth-child(5) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jobs-table th:nth-child(6), .jobs-table td:nth-child(6) { width: 150px; text-align: right; }
/* The download labels are two short lines in a 150px column; the shared .btn
   fixes height at 34px and let the second line spill out of the pill. */
.jobs-table .jobs-action-cell .btn {
  height: auto;
  min-height: 34px;
  padding-top: 5px;
  padding-bottom: 5px;
  line-height: 1.25;
  text-align: left;
}
/* One action per row: never let the chevron wrap underneath an Open link. */
.jobs-table .jobs-action-cell .row-actions { justify-content: flex-end; flex-wrap: nowrap; }

.jobs-table td:nth-child(1) { min-width: 0; }
.jobs-table td:nth-child(1) > .doc {
  display: block;
  overflow: hidden;
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.jobs-table td:nth-child(1) > .jobs-doc-meta,
.jobs-table td:nth-child(1) > .mono.col-sec {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.jobs-table td:nth-child(1) > .mono.col-sec { color: var(--faintest); font-size: 11px; }

/* Source-kind marker reads as a small badge, not as part of the filename. */
.ft {
  display: inline-flex;
  align-items: center;
  padding: 1px 5px;
  border-radius: 4px;
  margin-right: 7px;
  background: var(--chip-bg);
  color: var(--chip-fg);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: .06em;
  vertical-align: 1px;
}

.jobs-table .status-stack { gap: 4px; }
.jobs-table .status-stack .pill { white-space: nowrap; }

/* --- Embedded Clerk profile ------------------------------------------------
   Carried over from the retired account-only sheet, now deleted. The
   navbar title is hidden so the page keeps one unskipped heading outline;
   without this rule Clerk contributes a second "Account" heading. */

#clerk-user-profile,
[data-clerk-user-profile] {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--card);
}
[data-clerk-user-profile] [data-localization-key="userProfile.navbar.title"] { display: none; }
[data-clerk-user-profile] .cl-rootBox,
[data-clerk-user-profile] .cl-userProfile-root { width: 100%; }

/* ==========================================================================
   21. Responsive
   Desktop-first; the layout holds to roughly 900px. Tables scroll horizontally
   below their min-widths rather than collapsing columns.
   ========================================================================== */

@media (max-width: 1000px) {
  .lfw-pane { padding: 26px 20px 56px; }
  header.topbar { padding: 0 20px; }
}

@media (max-width: 700px) {
  .job-processing-panel .proc-meta { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .job-processing-panel .job-pipe { gap: 6px; }
  .job-processing-panel .pstep .nm { font-size: 10.5px; }
  .job-processing-panel .pstep .st { font-size: 9.5px; }
}

@media (max-width: 860px) {
  .shell { height: auto; min-height: 100vh; overflow: visible; }
  .sidebar {
    width: 100%;
    flex: 0 0 auto;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .shell { flex-direction: column; }
  .lfw-sidebar-spacer { display: none; }
  .wd-nav { flex-direction: row; overflow-x: auto; }
  .wd-nav a { white-space: nowrap; }
  .lfw-pane { overflow: visible; }
  .lfw-head h1 { font-size: 27px; }
}

/* Each conversion option has its own balance; packs are shared and shown once. */
.sb-usage:has(.allowance-balance) { display: flex; flex-direction: column; align-items: stretch; gap: 12px; }
.allowance-balance { min-width: 0; }
.allowance-title { color: var(--muted); font-size: 11px; font-weight: 600; line-height: 1.4; }
.allowance-amount { color: var(--ink); font-family: var(--serif); font-size: 21px; line-height: 1.6; }
.allowance-detail { color: var(--muted-2); font-size: 11px; line-height: 1.5; }
.allowance-balance progress { display: block; width: 100%; height: 5px; margin: 5px 0; accent-color: var(--accent); }

/* Shared workspace support dialog. Native dialog supplies focus containment. */
.workspace-support { width: min(480px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); overflow: auto; box-sizing: border-box; border: 1px solid var(--line); border-radius: 14px; padding: 26px; background: var(--card); color: var(--ink); }
.workspace-support::backdrop { background: rgb(0 0 0 / 45%); }
.workspace-support h2 { margin: 0 0 12px; }
.workspace-support p { font-size: 14px; line-height: 1.5; }
.workspace-support label { display: block; margin: 16px 0 6px; font-size: 14px; font-weight: 600; }
.workspace-support input, .workspace-support textarea { width: 100%; box-sizing: border-box; padding: 10px; border: 1px solid var(--line); border-radius: 6px; background: var(--card); color: inherit; font: inherit; }
.workspace-support textarea { resize: vertical; }
.workspace-support .support-hint { font-size: 12px; }
.workspace-support .support-actions { display: flex; justify-content: flex-end; gap: 10px; }
.workspace-support button { padding: 10px 16px; border: 1px solid var(--line); border-radius: 6px; cursor: pointer; background: var(--card); color: inherit; font: inherit; }
.workspace-support button[type=submit] { background: var(--btn-bg); color: var(--btn-fg); }
.workspace-support button:disabled { opacity: .6; cursor: wait; }
