/* ==========================================================================
   Quanta Projects — styled to match the Quanta platform.

   The token block below mirrors the portal's (`portal.quantainnovation.ai`
   templates/_base.html :root), pinned to the DEFAULT Quanta branding values
   rather than resolved per tenant. Same names, same values, so the two apps
   read as one product and a change made there can be copied straight across.

   Why copied and not shared: the portal's CSS is a ~1,200-line inline <style>
   block inside a Jinja template, with tenant branding interpolated into :root
   at render time. There is no file to import, and extracting one would mean
   refactoring a live app plus serving CSS cross-domain. Copying the token
   layer gets the same look with no coupling.

   Scope note: this styles the app's CHROME only. Design sketches are themed
   separately, in the client's own palette, by design_file() injecting --brand*
   into the iframe. Nothing here reaches inside that frame.
   ========================================================================== */

:root {
  /* Brand — TEAL, this app's own accent (James, 2026-08-14). Deliberately not
     the platform's sky blue: two tabs of the same product should not look
     identical. The Quanta Q in the banner stays sky, so the accent lives
     alongside it rather than replacing it. */
  --primary: #14b8a6;
  --primary-dark: #0d9488;
  --primary-light: #2dd4bf;
  --primary-rgb: 20, 184, 166;
  --primary-light-rgb: 45, 212, 191;
  /* Teal at full strength measures 2.49:1 on white — fine behind white button
     text, nowhere near enough for a 13px link. --primary-dark only reaches
     3.74:1, still short of the 4.5:1 AA needs for small text, so link text
     drops a further step to teal-700 (5.45:1). Same hue, readable, and only
     text uses it — fills and borders keep the full-strength accent. */
  --accent-text: #0f766e;
  --secondary: #0f172a;
  --secondary-rgb: 15, 23, 42;
  --button-text: #ffffff;

  /* Navigation */
  --nav-bg: #0f172a;
  --nav-text: #ffffff;
  --nav-border: rgba(255, 255, 255, 0.08);

  /* Surfaces */
  --bg-primary: #ffffff;
  --bg-secondary: #f8fafc;
  --bg-tertiary: #f1f5f9;
  --bg-elevated: #e2e8f0;

  /* Text */
  --text-primary: #0f172a;
  --text-secondary: #475569;
  --text-muted: #94a3b8;

  /* Lines. --border-strong is local to this app: the portal's --border is a
     10% wash, which disappears on inputs and on the dashed empty states that
     carry a lot of the layout here. */
  --border: rgba(15, 23, 42, 0.1);
  --border-light: rgba(var(--secondary-rgb), 0.05);
  --border-strong: rgba(15, 23, 42, 0.18);

  /* Status */
  --success: #10b981;
  --warning: #d97706;
  --danger: #dc2626;
  --accent-blue: #2563eb;
  --accent-gold: #d97706;

  /* Auth page. The portal drops the card entirely — the form floats on the
     page aurora — so these are transparent by design, not unfinished. The
     input fill is a translucent white wash so the field sits ABOVE the glow
     rather than compositing into it. */
  --bg-page: var(--bg-primary);
  --bg-primary-rgb: 255, 255, 255;
  --auth-page-bg: #ffffff;
  --auth-card-bg: transparent;
  --auth-card-border: transparent;
  --auth-card-shadow: none;
  --auth-header-bg: transparent;
  --auth-input-bg: rgba(var(--bg-primary-rgb), 0.72);
  --auth-input-border: var(--border);
  --auth-header-pad-bottom: 14px;

  /* The hero wordmark ramp, same shape as the marketing site's --gradient-text
     (dark → mid → light at 135deg). Derived from the accent so it is one
     token change to re-theme, never a second place to edit. */
  --gradient-text: linear-gradient(135deg,
      var(--primary-dark) 0%, var(--primary) 50%, var(--primary-light) 100%);

  /* Page-aurora lobes: teal leads, violet stays as the second. Violet is the
     complement that keeps the glow from going flat — a sky second lobe would
     sit too near the teal and read as one muddy wash. */
  --aurora-primary-rgb: 20, 184, 166;
  --aurora-accent-rgb: 139, 92, 246;

  /* Fixed chrome heights. The viewer sizes itself against the viewport minus
     these two bands, so they are stated once here and referenced — a height
     hard-coded into two calc()s disagrees the moment one of them changes.
     Both bars declare `height`, not padding, so these are exact by
     construction rather than measured. */
  --topbar-h: 56px;
  --viewerbar-h: 52px;

  /* Shadows */
  --shadow-rgb: var(--secondary-rgb);
  --shadow-sm: 0 1px 3px rgba(var(--shadow-rgb), 0.06);
  --shadow-md: 0 8px 24px rgba(var(--shadow-rgb), 0.10);
  --shadow-lg: 0 16px 40px rgba(var(--shadow-rgb), 0.16);
  /* The portal's lifted panel shadow (its *-table-wrapper rules): a tight
     contact shadow plus a wide soft one. */
  --shadow-panel: 0 1px 2px rgba(var(--shadow-rgb), 0.04),
                  0 14px 34px rgba(var(--shadow-rgb), 0.06);

  /* Status tints. The portal does not tokenise its pastel fills, so these are
     local — named rather than inlined so the amber acting-as strip and the
     amber 'waiting on you' callout cannot drift apart. */
  --tint-warn-bg: #fef3c7;
  --tint-warn-line: #fde68a;
  --tint-warn-text: #92400e;
  --tint-warn-strong: #78350f;
  --tint-ok-bg: #dcfce7;
  --tint-ok-line: #bbf7d0;
  --tint-ok-text: #166534;
  --tint-info-bg: #e0f2fe;
  --tint-info-line: #bae6fd;
  --tint-info-text: #075985;
  --tint-danger-bg: #fef2f2;
  --tint-danger-line: #fecaca;
  --tint-danger-text: #b91c1c;
  --tint-warn-soft: #fffbeb;
  --tint-warn-edge: #fcd34d;
  --tint-warn-oncolor: #fffbeb;

  /* Semantic one-offs. Tokenised not for reuse but so the dark block below
     has something to override — a hex buried in a component rule is invisible
     to a theme. */
  --stage-signoff-bg: #dbeafe;
  --stage-signoff-text: #1d4ed8;
  --stage-ready-bg: #ede9fe;
  --stage-ready-text: #5b21b6;
  --anchor-text: #0369a1;
  --ok-text: #16a34a;
  --dot-yes: #16a34a;
  --dot-wait: #f59e0b;
  --btn-final-bg: #166534;
  --btn-final-bg-hover: #14532d;
  --danger-hover: #991b1b;
  /* The sketch is always a light document, so its frame stays white in both
     themes — a navy frame would tint the artefact being reviewed. */
  --frame-bg: #ffffff;

  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
}

/* ==========================================================================
   Dark theme — the portal's "orbit" palette (templates/_theme_tokens.html).

   Applied PER PAGE, not per session: base.html's `theme` block defaults to
   light and login.html overrides it to dark. So the signed-in app is light —
   matching the platform's light mode — while the entry screen keeps the orbit
   ground the portal's own login has, which is what makes the teal wordmark and
   the aurora read. Adding a user preference later means changing what fills
   that block, not touching this CSS.

   Identity tokens (--primary*) are deliberately NOT overridden: teal #14b8a6
   is already bright enough for dark surfaces, so it needs none of the lift the
   portal's _lift_for_dark applies to darker tenant accents.
   ========================================================================== */
html[data-theme="dark"] {
  color-scheme: dark;

  --bg-page: #060a14;
  --bg-primary: #0f1a2e;
  --bg-primary-rgb: 15, 26, 46;
  --bg-secondary: #131f36;
  --bg-tertiary: #182543;
  --bg-elevated: #1e2c4d;

  --text-primary: #f1f5f9;
  --text-secondary: #cbd5e1;
  --text-muted: #94a3b8;
  /* --secondary is used as a text colour; point it at the dark text token.
     --secondary-rgb is NOT changed: it feeds shadows, which stay dark. */
  --secondary: #f1f5f9;

  --border: rgba(148, 163, 184, 0.16);
  --border-light: rgba(255, 255, 255, 0.06);
  --border-strong: rgba(148, 163, 184, 0.28);

  --nav-bg: #0b1120;
  --nav-text: #f1f5f9;
  --nav-border: rgba(148, 163, 184, 0.12);

  --shadow-rgb: 2, 6, 18;

  /* Status colours lightened for contrast on dark surfaces.
     Green moved off emerald (#34d399, hue ~160°) to a truer green
     (hue ~142°): the teal accent sits at ~173°, and 13° of separation was
     not enough to keep "signed scope baseline" distinct from ordinary
     chrome. 31° is. The accent was chosen; the state colour gives way. */
  --success: #4ade80;
  --warning: #fbbf24;
  --danger: #f87171;
  --accent-gold: #f59e0b;
  --accent-blue: #60a5fa;
  --accent-text: var(--primary-light);

  /* Auth: a pale film lifts inputs off the gradient, where the light theme
     used a white wash. */
  --auth-page-bg: #060a14;
  --auth-input-bg: rgba(255, 255, 255, 0.07);
  --auth-input-border: rgba(148, 163, 184, 0.28);

  /* Pastel fills invert to translucent washes — a #fef3c7 block on a near
     black page reads as a light box stuck to the screen. */
  --tint-warn-bg: rgba(251, 191, 36, 0.15);
  --tint-warn-line: rgba(251, 191, 36, 0.30);
  --tint-warn-text: #fbbf24;
  --tint-warn-strong: #fcd34d;
  --tint-warn-soft: rgba(251, 191, 36, 0.10);
  --tint-warn-edge: rgba(251, 191, 36, 0.35);
  --tint-warn-oncolor: #1c1408;
  --tint-ok-bg: rgba(74, 222, 128, 0.15);
  --tint-ok-line: rgba(74, 222, 128, 0.30);
  --tint-ok-text: #4ade80;
  --tint-info-bg: rgba(96, 165, 250, 0.15);
  --tint-info-line: rgba(96, 165, 250, 0.30);
  --tint-info-text: #93c5fd;
  --tint-danger-bg: rgba(248, 113, 113, 0.15);
  --tint-danger-line: rgba(248, 113, 113, 0.30);
  --tint-danger-text: #f87171;

  --stage-signoff-bg: rgba(96, 165, 250, 0.18);
  --stage-signoff-text: #93c5fd;
  --stage-ready-bg: rgba(167, 139, 250, 0.20);
  --stage-ready-text: #c4b5fd;
  --anchor-text: #7dd3fc;
  --ok-text: #4ade80;
  --dot-yes: #4ade80;
  --dot-wait: #fbbf24;
  --btn-final-bg: #15803d;
  --btn-final-bg-hover: #166534;
  --danger-hover: #fca5a5;
}

*, *::before, *::after { box-sizing: border-box; }
body {
  margin: 0;
  /* Inter, as the platform uses. Loaded in base.html; the stack falls back to
     the system UI font if Google Fonts is blocked. */
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  color: var(--text-primary);
  /* White page with tinted panels on it, as the portal does in light mode -
     the inverse of the tinted-page/white-card arrangement this app had. */
  background: var(--bg-page);
}
h1, h2, h3 { margin: 0 0 .4em; line-height: 1.25; }
a { color: var(--accent-text); }

/* ------------------------------------------------------------------ chrome */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 0 20px; height: var(--topbar-h);
  background: var(--nav-bg); color: var(--nav-text);
  border-bottom: 1px solid var(--nav-border);
}
.brand { display: flex; align-items: center; gap: 10px;
  color: inherit; text-decoration: none; font-weight: 600; }
.brand img { height: 26px; width: auto; }
.topbar-right { display: flex; align-items: center; gap: 14px; font-size: 13px; }
.topbar-right .btn { white-space: nowrap; }
.who { display: flex; align-items: center; gap: 8px; opacity: .9; }
.who em { font-style: normal; opacity: .65; }

.wrap { max-width: 1100px; margin: 0 auto; padding: 32px 20px 64px; }
.page-title { font-size: 24px; margin-bottom: 20px; letter-spacing: -0.01em; }
.page-lead { margin: -12px 0 24px; color: var(--text-secondary); font-size: 14px;
  max-width: 62ch; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; color: var(--text-muted); }

/* --------------------------------------------------------------- acting as */
/* The topbar chip: everything below the chrome belongs to another company's
   account, so the fact has to sit somewhere permanent — but it is a label,
   not a control surface. Amber on the navy bar, and a link to the Clients
   page, which is where the view switcher and Leave now live. */
.acting-chip { display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 12px; border-radius: 999px; font-size: 12px;
  background: rgba(251, 191, 36, 0.14); border: 1px solid rgba(251, 191, 36, 0.32);
  color: #fcd34d; text-decoration: none; white-space: nowrap;
  transition: background .12s, border-color .12s; }
.acting-chip:hover { background: rgba(251, 191, 36, 0.22);
  border-color: rgba(251, 191, 36, 0.5); }
.acting-chip strong { font-weight: 600; }
.acting-chip em { font-style: italic; opacity: .8; }
.acting-chip .mono { color: inherit; opacity: .65; }
.acting-dot { width: 7px; height: 7px; border-radius: 50%;
  background: var(--warning); flex: none; }

/* The controls, on the Clients page: a card, not a page-wide strip. */
.acting-panel { display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: var(--bg-secondary); border: 1px solid var(--border);
  border-left: 3px solid var(--warning); border-radius: var(--radius-md);
  padding: 14px 18px; margin-bottom: 24px; box-shadow: var(--shadow-sm); }
.acting-panel form { margin: 0; }
.acting-panel-info { flex: 1 1 320px; }
.acting-panel-info h2 { font-size: 15px; margin: 0 0 2px; }
.acting-panel-info p { margin: 0; font-size: 13px; color: var(--text-secondary); }
.acting-panel-views { display: flex;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  overflow: hidden; }
.viewbtn { padding: 6px 14px; font: inherit; font-size: 13px; cursor: pointer;
  border: 0; border-right: 1px solid var(--border); background: var(--bg-primary);
  color: var(--text-secondary); }
.viewbtn:last-child { border-right: 0; }
.viewbtn:hover { color: var(--text-primary); }
.viewbtn.active { background: var(--primary); color: var(--button-text); font-weight: 600; }
.acting-panel-stop { font-size: 13px; }
.draft-note { background: var(--bg-secondary); border: 1px dashed var(--border-strong);
  border-radius: 10px; padding: 12px 14px; margin: 0 0 20px; font-size: 13px;
  color: var(--text-secondary); }

/* The topbar carries a lot for staff at phone width. The chip degrades to its
   dot + client name; the user's own tenant label goes first. */
@media (max-width: 640px) {
  .topbar { gap: 10px; padding: 0 14px; }
  .topbar-right { gap: 10px; font-size: 12px; }
  .who em, .who .tag-admin { display: none; }
  .brand span { display: none; }
  .acting-chip { padding: 4px 9px; }
  .acting-chip .mono, .acting-chip em { display: none; }
}

/* ------------------------------------------------------------------ buttons */
/* The UA stylesheet's [hidden] { display: none } is an author-sheet loss
   against anything here that sets display — .btn did exactly that, so a
   button written <button class="btn" hidden> rendered anyway. Standard fix,
   and it has to outrank every display rule below, hence !important. */
[hidden] { display: none !important; }

.btn {
  display: inline-block; padding: 9px 16px; border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong); background: var(--bg-primary);
  color: var(--text-primary);
  font: inherit; font-size: 14px; cursor: pointer; text-decoration: none;
  transition: border-color .12s, background .12s;
}
.btn:hover { border-color: var(--text-muted); }
.btn-primary { background: var(--primary); border-color: var(--primary);
  color: var(--button-text); }
.btn-primary:hover { background: var(--primary-dark); border-color: var(--primary-dark); }
.btn-quiet { background: transparent; border-color: transparent; color: inherit; opacity: .85; }
.btn-quiet:hover { opacity: 1; border-color: transparent; }
.btn-block { display: block; width: 100%; }
.link { background: none; border: 0; padding: 0; color: var(--accent-text);
  font: inherit; font-size: 13px; cursor: pointer; text-decoration: underline; }

/* ------------------------------------------------------------------- login */
/* Ported from the portal's templates/login.html, rule for rule. The form has
   NO card: it floats on the page aurora, which is why --auth-card-* are all
   transparent. Getting this wrong (a white card on navy, a 34px logo) was
   what made the two apps look unrelated. */

/* The ambient wash every page carries, and the stronger auth-page aurora on
   top of it. Both are ::before layers pinned behind the content. */
body::before {
  content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background:
    radial-gradient(ellipse at 20% 0%, rgba(var(--primary-rgb), 0.04) 0%, transparent 50%),
    radial-gradient(ellipse at 80% 100%, rgba(var(--primary-rgb), 0.03) 0%, transparent 50%);
}
body.page-aurora { background: var(--auth-page-bg); }
body.page-aurora::before {
  background:
    radial-gradient(700px 480px at 10% 2%, rgba(var(--aurora-primary-rgb), 0.24), transparent 52%),
    radial-gradient(780px 540px at 90% 98%, rgba(var(--aurora-accent-rgb), 0.17), transparent 52%),
    radial-gradient(520px 400px at 84% 8%, rgba(var(--aurora-primary-rgb), 0.09), transparent 55%),
    radial-gradient(120% 120% at 50% 45%, transparent 40%, rgba(var(--secondary-rgb), 0.06) 100%),
    var(--bg-page);
}
html[data-theme="dark"] body.page-aurora::before {
  background:
    radial-gradient(700px 480px at 10% 2%, rgba(var(--primary-rgb), 0.24), transparent 52%),
    radial-gradient(780px 540px at 90% 98%, rgba(var(--aurora-accent-rgb), 0.17), transparent 52%),
    radial-gradient(520px 400px at 84% 8%, rgba(var(--primary-light-rgb), 0.09), transparent 55%),
    radial-gradient(120% 120% at 50% 45%, transparent 40%, rgba(0, 0, 0, 0.38) 100%),
    linear-gradient(160deg, #060a14 0%, #0b1120 45%, #111c33 100%);
}

/* Content sits above the fixed glow. */
.auth-wrapper, .topbar, .actingbar, main { position: relative; z-index: 1; }

.auth-wrapper { width: 100%; max-width: 100%; min-height: 100vh;
  display: flex; align-items: center; justify-content: center; padding: 40px 20px; }
.auth-container { width: 100%; max-width: 460px; background: var(--auth-card-bg);
  border-radius: 20px; box-shadow: var(--auth-card-shadow); overflow: hidden;
  border: 1px solid var(--auth-card-border); }
.auth-header { text-align: center;
  padding: 40px 40px var(--auth-header-pad-bottom);
  background: var(--auth-header-bg); border-bottom: 1px solid var(--auth-card-border); }
/* Height-budgeted rather than width-budgeted, so a squarish mark and a wide
   wordmark both land at a sensible size. */
.auth-logo { max-height: 84px; max-width: 300px; width: auto; height: auto;
  margin: 0 auto 14px; display: block; object-fit: contain;
  filter: drop-shadow(0 4px 16px rgba(var(--primary-rgb), 0.2)); }
.auth-header h1 { font-size: 30px; font-weight: 700; color: var(--text-primary);
  margin-bottom: 6px; letter-spacing: -0.6px; }
/* The marketing site's hero treatment (quantainnovation.ai .gradient-text, as
   on "Time" in "Give Your Business Its Time Back"): a 135deg three-stop ramp
   clipped to the glyphs. Built from the accent tokens rather than fixed hexes,
   so changing the theme moves the wordmark with it.
   -webkit-* prefixes are load-bearing, not legacy: background-clip: text is
   still prefixed in Safari. */
.gradient-text {
  background: var(--gradient-text);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.auth-header p { color: var(--text-secondary); font-size: 15px; font-weight: 400;
  margin: 0; }
.auth-body { padding: 40px; }
.auth-form { display: flex; flex-direction: column; gap: 20px; }
.form-group { display: flex; flex-direction: column; gap: 8px; }
.form-group label { font-size: 14px; font-weight: 600; color: var(--text-primary); }
.form-group input { padding: 14px 16px; border: 2px solid var(--auth-input-border);
  border-radius: 12px; font-size: 15px; font-family: inherit;
  transition: all 0.2s ease; background: var(--auth-input-bg);
  color: var(--text-primary); }
.form-group input:focus { outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 4px rgba(var(--primary-rgb), 0.1); }
.form-group input::placeholder { color: var(--text-secondary); }
.auth-btn { padding: 16px 24px; background: var(--primary); color: var(--button-text);
  border: none; border-radius: 12px; font-size: 16px; font-weight: 600;
  font-family: inherit; cursor: pointer; transition: all 0.2s ease;
  display: flex; align-items: center; justify-content: center; gap: 10px; }
.auth-btn:hover { background: var(--primary-dark); transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(var(--primary-rgb), 0.25); }
.auth-btn:active { transform: translateY(0); }
.auth-btn i { font-size: 14px; }
.auth-footer { text-align: center; margin-top: 28px; padding-top: 28px;
  border-top: 1px solid var(--border); }
.auth-footer p { color: var(--text-secondary); font-size: 14px; margin: 0; }

.alert { padding: 14px 18px; border-radius: 12px; font-size: 14px;
  margin-bottom: 20px; display: flex; align-items: center; gap: 10px; }
.alert-error { background: var(--tint-danger-bg);
  border: 1px solid var(--tint-danger-line); color: var(--danger); }
.alert i { font-size: 16px; }

@media (max-width: 480px) {
  .auth-wrapper { padding: 20px 16px; }
  .auth-header { padding: 32px 24px 24px; }
  .auth-body { padding: 24px; }
  .auth-header h1 { font-size: 22px; }
  .auth-logo { max-height: 64px; max-width: 240px; }
}

/* ------------------------------------------------------------------- cards */
.grid { display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); }
.card { display: block; background: var(--bg-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 18px; text-decoration: none; color: inherit;
  box-shadow: var(--shadow-sm);
  transition: border-color .12s, transform .12s, box-shadow .12s; }
.card:hover { border-color: var(--primary); transform: translateY(-1px);
  box-shadow: var(--shadow-md); }
.card-head { display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 10px; }
.card h2 { font-size: 17px; }
.card-sub { margin: 0; color: var(--text-secondary); font-size: 13px; }
.card-foot { display: flex; justify-content: space-between; align-items: center;
  margin-top: 16px; font-size: 12px; color: var(--text-secondary); }

/* Stage pills. One per project stage, and they must stay visually distinct -
   'ready to seal' and 'sign-off sent' previously resolved to the same blue
   because .stage-ready was declared twice. */
.stage { font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; padding: 3px 8px; border-radius: 999px; }
.stage-brief { background: var(--tint-info-bg); color: var(--tint-info-text); }
.stage-draft { background: var(--bg-elevated); color: var(--text-secondary); }
.stage-review { background: var(--tint-warn-bg); color: var(--tint-warn-text); }
.stage-rework { background: var(--tint-danger-bg); color: var(--tint-danger-text); }
.stage-signoff { background: var(--stage-signoff-bg); color: var(--stage-signoff-text); }
.stage-ready { background: var(--stage-ready-bg); color: var(--stage-ready-text); }
.stage-signed { background: var(--tint-ok-bg); color: var(--tint-ok-text); }

.tag { font-size: 11px; background: var(--bg-elevated); color: var(--text-secondary);
  padding: 3px 8px; border-radius: 999px; }
.tag-admin { background: var(--primary); color: var(--button-text); }
.pill { background: var(--tint-info-bg); color: var(--tint-info-text);
  padding: 2px 8px; border-radius: 999px; }
.pill-quiet { background: var(--bg-tertiary); color: var(--text-secondary); }
.pill-warn { background: var(--tint-warn-bg); color: var(--tint-warn-text); }
.ok { color: var(--ok-text); font-weight: 600; }
.muted { color: var(--text-muted); }

.empty { background: var(--bg-secondary); border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  padding: 48px 24px; text-align: center; color: var(--text-secondary); }
.empty h2 { font-size: 18px; color: var(--text-primary); }

/* ------------------------------------------------------- designs table */
/* The wrapper scrolls, not the page: nine columns cannot fit a phone. */
.table-wrap { overflow-x: auto; background: var(--bg-primary);
  border: 1px solid var(--border-light); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-panel); }
.designs { width: 100%; border-collapse: collapse; font-size: 13px;
  min-width: 900px; }
/* 11px sides, not 14: nine columns multiply the gutter by eighteen, which was
   enough on its own to push the last column out of the box at 1280. */
.designs th, .designs td { text-align: left; padding: 12px 11px;
  border-bottom: 1px solid var(--bg-tertiary); vertical-align: top; }
.designs thead th { font-size: 11px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-secondary);
  background: var(--bg-secondary);
  border-bottom: 1px solid var(--border); white-space: nowrap; }
.designs thead .sub { font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--text-muted); }
.designs thead th.sub { border-top: 0; padding-top: 0; }
/* The spanning "Sign-offs" header, centred over its three columns and ruled
   underneath so the grouping reads at a glance. */
.designs thead th.group { text-align: center; border-bottom: 1px solid var(--border);
  padding-bottom: 6px; }
.designs thead th[rowspan="2"] { vertical-align: bottom; }
.designs tbody tr:last-child th, .designs tbody tr:last-child td { border-bottom: 0; }
.designs tbody tr:hover { background: var(--bg-secondary); }
/* The whole row opens the design, so the whole row has to look like it does:
   a pointer across all nine columns, and the title underlining on ROW hover
   rather than only when the cursor happens to be over the words. */
.designs tbody tr.is-clickable { cursor: pointer; }
.designs tbody tr.is-clickable:hover .cell-design a {
  color: var(--accent-text); text-decoration: underline; }
/* Keyboard users tab to the anchor, not the row — make that land visibly. */
.designs tbody tr.is-clickable:focus-within { background: var(--bg-secondary); }
.cell-design a:focus-visible { outline: 2px solid var(--primary);
  outline-offset: 2px; border-radius: 3px; }
.designs .num { text-align: right; white-space: nowrap; }
.designs thead .num { text-align: right; }
.cell-design { font-weight: 600; min-width: 210px; }
.cell-design a { color: inherit; text-decoration: none; }
.cell-design a:hover { color: var(--accent-text); text-decoration: underline; }
.cell-sub { display: block; margin-top: 3px; font-size: 11px; font-weight: 400;
  color: var(--text-muted); }
/* A person's name and a two-word link are the wrong things to hyphenate into
   three lines when the table has room to spare - the auto layout gives the
   width to whichever column will take it, so these have to refuse. */
.cell-owner { white-space: nowrap; }
.cell-owner .cell-sub { white-space: normal; }
.cell-when, .cell-brief { white-space: nowrap; }
.designs .stage { display: inline-block; white-space: nowrap; }

/* ---------------------------------------------------------- client roster */
/* Uniform cards - no per-tenant colour. The picker is Quanta chrome, and a
   swatch per client made it read as a branding gallery rather than a list of
   accounts. */
.client-card { background: var(--bg-secondary); border: 1px solid var(--border);
  border-top: 3px solid var(--primary);
  border-radius: var(--radius-lg); padding: 18px; margin: 0;
  box-shadow: var(--shadow-sm);
  transition: border-color .12s, transform .12s, box-shadow .12s; }
.client-card:hover { transform: translateY(-1px); box-shadow: var(--shadow-md); }
.client-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.client-head h2 { font-size: 17px; margin: 0; }
.client-head .tag-admin { margin-left: auto; }
.client-stats { list-style: none; margin: 0 0 16px; padding: 0;
  display: flex; flex-wrap: wrap; gap: 12px; font-size: 12px;
  color: var(--text-secondary); }
.client-stats strong { color: var(--text-primary); font-size: 13px; }
.client-actions { display: flex; gap: 8px; }
.client-actions .btn { font-size: 13px; padding: 7px 14px; }

/* ------------------------------------------------------------ review tabs */
/* Brief | Design | Sign Offs — a segmented pill. On the viewer pages it sits
   CENTRED INSIDE the viewer bar (the .vb-tabs slot), so the chrome is one
   slim band instead of two stacked ones; on the brief page, a document, it
   renders standalone above the content with its own spacing. */
.review-tabs { display: flex; justify-content: center; }
.review-tabs-inner { display: inline-flex; gap: 3px; padding: 4px;
  background: var(--bg-tertiary); border: 1px solid var(--border);
  border-radius: 999px; }
.review-tab { padding: 5px 16px; border-radius: 999px; font-size: 13px;
  font-weight: 500; color: var(--text-secondary); text-decoration: none;
  white-space: nowrap; transition: background-color .15s ease, color .15s ease; }
.review-tab:hover:not(.is-active):not(.is-empty) { color: var(--text-primary);
  background: var(--bg-primary); }
.review-tab.is-active { background: var(--primary); color: #fff; font-weight: 600; }
/* A tab with nowhere to point: still readable, plainly not a link, and it
   carries the reason as a tooltip rather than shrinking the bar. */
.review-tab.is-empty { color: var(--text-muted); cursor: not-allowed; }
/* A FINISHED stage (brief agreed, scoped version produced, sketch sealed):
   the tick is the stage-complete mark, not part of the label, so it stays
   subtle — green on the pill ground, white when the tab is active. */
.review-tab .tab-check { margin-right: 6px; font-weight: 700;
  color: var(--ok-text); }
.review-tab.is-active .tab-check { color: #fff; }
/* Screen-reader text for the tick, since ✓ alone reads as nothing useful. */
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0;
  margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  border: 0; }
/* Standalone (brief page, where it is a direct child of <main> rather than a
   slot in the viewer bar): give the pill the breathing room the bar provides
   elsewhere, and a lifted ground since it floats on the page. */
main > .review-tabs { margin: 0 0 20px; }
main > .review-tabs .review-tabs-inner { background: var(--bg-primary);
  box-shadow: var(--shadow-sm); }

/* ------------------------------------------------------------------ viewer */
.viewer-body { background: var(--bg-elevated); }
.viewer { padding: 0; }
/* One slim band: identity on the left, the review tabs dead centre, controls
   on the right. The two 1fr gutters keep the tabs centred on the SCREEN, not
   on whatever is left after the title — so they hold still when the title
   length or the control set changes between pages. Height is declared, not
   emergent: the split below subtracts it. */
.viewer-bar { display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center; gap: 12px; padding: 0 12px;
  height: var(--viewerbar-h); background: var(--bg-primary);
  border-bottom: 1px solid var(--border); }
.vb-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.vb-left h1 { font-size: 15px; margin: 0; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.vb-tabs { display: flex; justify-content: center; }
.vb-right { display: flex; align-items: center; justify-content: flex-end;
  gap: 10px; }
.back { font-size: 13px; text-decoration: none; color: var(--text-secondary);
  white-space: nowrap; }
.back:hover { color: var(--accent-text); }
#version-select { font: inherit; font-size: 13px; padding: 5px 8px;
  border: 1px solid var(--border-strong); border-radius: 7px;
  background: var(--bg-primary); }

/* Panel toggles — icon-only. The glyph carries which panel; 32px keeps a
   comfortable pointer target next to the 13px chrome around it. */
.icon-btn { position: relative; display: inline-flex; align-items: center;
  justify-content: center; width: 32px; height: 32px; padding: 0;
  border: 1px solid transparent; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-secondary); cursor: pointer;
  transition: background .12s, color .12s, border-color .12s; }
.icon-btn:hover { background: var(--bg-secondary); color: var(--text-primary); }
.icon-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.icon-btn svg { width: 19px; height: 19px; display: block; fill: none;
  stroke: currentColor; stroke-width: 1.5; stroke-linecap: round;
  stroke-linejoin: round; }

/* Floating reopen handles, directly beneath the bar at the screen edge their
   panel slides from — inside the split, not up in the title bar. Lifted off
   the stage on a card ground (the sketch scrolls under them), and shown ONLY
   while their panel is shut: an open panel closes from its own head, so a
   second control mirroring its state would be noise. */
.panel-tab { position: absolute; top: 10px; z-index: 6;
  background: var(--bg-primary); border-color: var(--border);
  box-shadow: var(--shadow-sm); }
.panel-tab:hover { background: var(--bg-primary); border-color: var(--primary);
  color: var(--accent-text); }
.panel-tab-left { left: 10px; }
.panel-tab-right { right: 10px; }
.viewer-split.bp-open .panel-tab-left { display: none; }
.viewer-split.cp-open .panel-tab-right { display: none; }
/* While a handle is showing, the stage cedes it a gutter on that side, so it
   floats beside the sign-off banner and the sketch rather than on top of
   them. The left rule also checks [hidden]: that handle only exists at all
   when the sketch declares coverage. */
.viewer-split:not(.bp-open) .panel-tab-left:not([hidden]) ~ .stage-pane {
  padding-left: 52px; }
.viewer-split:not(.cp-open) .stage-pane { padding-right: 52px; }
/* Navy rather than the accent, because the badge has to stay visible on the
   teal fill the button takes when the panel is open. */
.icon-badge { position: absolute; top: -5px; right: -5px; min-width: 17px;
  height: 17px; padding: 0 4px; border-radius: 9px; background: var(--secondary);
  color: #fff; border: 2px solid var(--bg-primary);
  font-size: 10px; font-weight: 700; line-height: 13px; text-align: center;
  font-variant-numeric: tabular-nums; }

.devices { display: flex; border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); overflow: hidden; }
.dev { padding: 6px 12px; font: inherit; font-size: 13px; border: 0;
  background: var(--bg-primary); cursor: pointer;
  border-right: 1px solid var(--border); }
.dev:last-child { border-right: 0; }
.dev.active { background: var(--primary); color: var(--button-text); }

.banner { padding: 10px 20px; font-size: 13px;
  background: var(--tint-info-bg); color: var(--tint-info-text);
  border-bottom: 1px solid var(--tint-info-line); }
.banner-ok { background: var(--tint-ok-bg); color: var(--tint-ok-text);
  border-bottom: 1px solid var(--tint-ok-line); }
.banner-warn { background: var(--tint-warn-bg); color: var(--tint-warn-text);
  border-bottom: 1px solid var(--tint-warn-line); }
/* On the design page the banner sits in the stage column, above the sketch it
   describes, so the side panels can run the full height of the screen. There
   it is a rounded callout rather than a full-bleed strip. */
.stage-pane .banner { border: 1px solid var(--tint-info-line);
  border-radius: var(--radius-md); margin: 0 0 14px; flex: none; }
.stage-pane .banner-ok { border-color: var(--tint-ok-line); }
.stage-pane .banner-warn { border-color: var(--tint-warn-line); }

/* The viewer is an APP layout, not a document: exactly the viewport minus the
   two bars above it, with each pane scrolling itself. That is what puts both
   side panels flush against the viewer bar and running to the bottom of the
   screen, whatever the sketch or the comment thread is doing. */
.viewer-split {
  position: relative; /* anchors the floating .panel-tab reopen handles */
  height: calc(100vh - var(--topbar-h) - var(--viewerbar-h));
  overflow: hidden; }
.stage-pane { display: flex; flex-direction: column; padding: 20px;
  overflow: auto; min-width: 0; }
.frame-holder { width: 100%; flex: 1 1 auto; min-height: 0;
  background: var(--frame-bg);
  border-radius: 10px; box-shadow: var(--shadow-md); overflow: hidden; }
/* The phone preview keeps a real handset's proportions (390 x 844 - the
   iPhone 12-14 point grid): height from the available space, width from the
   aspect ratio, so a short window scales the whole phone down rather than
   squashing it. */
.frame-holder.is-device { flex: 0 1 844px; width: auto; aspect-ratio: 390 / 844;
  align-self: center; border: 8px solid var(--secondary); border-radius: 30px; }
#design-frame { display: block; width: 100%; height: 100%;
  border: 0; background: var(--frame-bg); }

/* ------------------------------------------------- brief coverage panel */
/* Open by default (viewer.js opens both panels on load, where they fit) but
   given its column only while open, so a closed panel costs the sketch no
   width at all. The grid override lives on the split rather than on the
   panel: a hidden element in a 3-column grid still leaves its track behind. */
/* Both side panels close independently, so the grid has four states and each
   is named rather than inferred — a hidden element still holds its track, so
   the columns have to be declared per combination. */
.viewer-split { display: grid; grid-template-columns: 1fr; }
.viewer-split.cp-open { grid-template-columns: 1fr 340px; }
.viewer-split.bp-open { grid-template-columns: 300px 1fr; }
.viewer-split.bp-open.cp-open { grid-template-columns: 300px 1fr 340px; }
/* Three columns need room the moment two of them are fixed: at 1100px wide,
   300 + 340 of chrome leaves the sketch under 400px, which is not a review of
   a dashboard. Below that the comments column yields to the panel you just
   asked for — you are either reading what a page should answer or writing
   about what it does. */
@media (max-width: 1279px) {
  .viewer-split.bp-open.cp-open { grid-template-columns: 280px 1fr; }
  .viewer-split.bp-open.cp-open .side { display: none; }
}
.brief-pane { background: var(--bg-primary); border-right: 1px solid var(--border);
  padding: 18px 16px; min-width: 0; overflow-y: auto; }
.bp-head { display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; margin-bottom: 4px; }
.bp-head h2 { font-size: 14px; margin: 0; }
.bp-close, .cp-close { border: 0; background: none; cursor: pointer;
  font-size: 20px; line-height: 1; color: var(--text-muted); padding: 0 2px; }
.bp-close:hover, .cp-close:hover { color: var(--text-primary); }
.bp-page { font-size: 12px; color: var(--text-secondary); margin: 0 0 14px; }
.bp-qs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 14px; }
.bp-q { font-size: 10.5px; font-weight: 700; letter-spacing: .03em;
  background: var(--primary); color: #fff; padding: 2px 8px; border-radius: 999px; }
.bp-sub { border-top: 1px solid var(--bg-tertiary); padding: 11px 0 2px; }
.bp-sub:first-of-type { border-top: 0; }
.bp-sub-id { font-size: 10.5px; font-weight: 700; color: var(--text-muted);
  font-variant-numeric: tabular-nums; }
.bp-sub-n { font-size: 13px; font-weight: 600; color: var(--text-primary);
  margin: 1px 0 3px; }
.bp-sub-f { font-size: 12px; color: var(--accent-text); margin: 0 0 3px; }
/* The reason a form was chosen is the point of the panel — it is what makes
   the choice arguable at review instead of inherited. */
.bp-why { font-size: 11.5px; color: var(--text-secondary); margin: 0 0 4px;
  font-style: italic; }
.bp-meta { font-size: 11px; color: var(--text-muted); margin: 0; }
.bp-ours { font-size: 10px; font-weight: 700; background: var(--bg-tertiary);
  color: var(--text-secondary); padding: 1px 6px; border-radius: 999px;
  margin-left: 5px; }
.bp-none { font-size: 12.5px; color: var(--text-secondary); }

.side { background: var(--bg-primary); border-left: 1px solid var(--border);
  padding: 20px; min-width: 0; overflow-y: auto; }
.side-head { display: flex; justify-content: space-between; align-items: baseline;
  gap: 8px; }
.side-head .muted { margin-left: auto; }
.side-head h2 { font-size: 15px; }

.composer { border: 1px solid var(--primary); border-radius: 10px;
  padding: 12px; margin-bottom: 12px; background: var(--bg-secondary); }
.composer.hidden, .hidden { display: none; }
.composer-anchor { display: flex; justify-content: space-between; gap: 8px;
  font-size: 12px; font-weight: 600; color: var(--anchor-text); margin-bottom: 8px; }
.composer textarea, .signoff-box textarea {
  width: 100%; font: inherit; font-size: 14px; padding: 8px 10px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  resize: vertical; }
.composer-actions { display: flex; gap: 8px; margin-top: 8px; }
.composer-error { color: var(--tint-danger-text); font-size: 12px; margin: 8px 0 0; }

.comments { list-style: none; margin: 16px 0 0; padding: 0; }
.no-comments { color: var(--text-muted); font-size: 13px; padding: 12px 0; }
.comment { border-top: 1px solid var(--border); padding: 12px 0; }
.comment.is-resolved { opacity: .55; }
.comment.is-resolved .comment-body { text-decoration: line-through; }
.comment-head { display: flex; justify-content: space-between; gap: 8px;
  font-size: 12px; }
.comment-anchor { font-size: 11px; font-weight: 600; color: var(--anchor-text);
  background: var(--tint-info-bg); display: inline-block; padding: 2px 7px;
  border-radius: 999px; margin: 6px 0; cursor: pointer; }
.flag-change { font-size: 11px; color: var(--tint-warn-text);
  background: var(--tint-warn-bg);
  display: inline-block; padding: 2px 7px; border-radius: 999px; margin: 4px 0; }
.comment-body { margin: 4px 0 8px; font-size: 14px; white-space: pre-wrap;
  overflow-wrap: anywhere; }
.comment-actions { display: flex; gap: 10px; align-items: center; font-size: 12px; }

.signoff-box { margin-top: 24px; padding-top: 18px; border-top: 2px solid var(--border); }
.signoff-box h3 { font-size: 14px; }
.signoff-box p { font-size: 12px; color: var(--text-secondary); margin: 0 0 10px; }
.signoff-box button { margin-top: 10px; }
.signoff-box select, .signoff-box input[type="date"] { width: 100%; margin-top: 8px;
  padding: 7px 9px; font: inherit; font-size: 13px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); background: var(--bg-primary); }

/* Recipient picker. Capped and scrollable so a tenant with thirty users does
   not push the sign-off button below the fold. */
.recipient-list { list-style: none; margin: 0; padding: 0; max-height: 180px;
  overflow-y: auto; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg-primary); }
.recipient-list li { border-bottom: 1px solid var(--bg-tertiary); }
.recipient-list li:last-child { border-bottom: 0; }
.recipient-list label { display: flex; gap: 8px; align-items: baseline;
  padding: 7px 10px; font-size: 13px; cursor: pointer; }
.recipient-list label:hover { background: var(--bg-secondary); }
.recipient-list .muted { font-size: 11px; }

/* "Waiting for your sign-off" - the reason someone opened the app at all, so
   it sits above the design list rather than inside a card. */
.callout { background: var(--tint-warn-soft); border: 1px solid var(--tint-warn-line);
  border-radius: var(--radius-md); padding: 16px 20px; margin-bottom: 22px; }
.callout h2 { font-size: 15px; color: var(--tint-warn-text); margin: 0 0 10px; }
.pending-list { list-style: none; margin: 0; padding: 0; }
.pending-list li { padding: 6px 0; border-top: 1px solid var(--tint-warn-line); }
.pending-list li:first-child { border-top: 0; }
.pending-list a { font-weight: 600; color: var(--text-primary); text-decoration: none; }
.pending-list a:hover { text-decoration: underline; }
.pending-list .pill { margin-left: 8px; }

@media (max-width: 900px) {
  /* Back to a document: the bar wraps onto two rows (tabs underneath), so the
     fixed-height budget no longer holds, and stacked panels want the page to
     scroll as one. */
  .viewer-bar { display: flex; flex-wrap: wrap; height: auto;
    padding: 10px 12px; row-gap: 8px; }
  .vb-left { flex: 1 1 auto; }
  .vb-right { flex: 0 0 auto; margin-left: auto; }
  .vb-tabs { order: 3; flex: 1 1 100%; }
  .viewer-split, .viewer-split.bp-open, .viewer-split.cp-open,
  .viewer-split.bp-open.cp-open { grid-template-columns: 1fr; }
  .viewer-split { height: auto; overflow: visible; }
  .brief-pane, .side { overflow-y: visible; }
  .brief-pane { border-right: 0; border-bottom: 1px solid var(--border); }
  .side { border-left: 0; border-top: 1px solid var(--border); }
  .frame-holder, .frame-holder.is-device { flex: none; }
  .frame-holder.is-device { width: min(390px, 100%); aspect-ratio: 390 / 844;
    height: auto; margin: 0 auto; }
  #design-frame { height: 70vh; }
  .frame-holder.is-device #design-frame { height: 100%; }
}

/* --------------------------------------------------------- sign-off page */
/* The sidebar's stacked panels become cards on their own page. Capped at a
   readable column rather than run to full width: every box here is a short
   list or a single decision, and a 1400px-wide Sign off button would be the
   easiest thing on the page to hit by accident. */
.signoff-page { max-width: 860px; margin: 0 auto; padding: 28px 20px 64px; }

/* The Brief and Data Audit tabs: a document column inside the viewer shell,
   the same footprint as .signoff-page so the four stage pages hold still
   under the tab bar. */
.brief-page { max-width: 860px; margin: 0 auto; padding: 24px 20px 64px; }
/* -12px top margin was sized for the page-head above it on the standalone
   brief page; inside the viewer shell the bar provides that rhythm. */
.brief-page .brief-meta { margin: 0 0 16px; }
.brief-page .signoff-box { margin-top: 24px; border: 1px solid var(--border);
  border-radius: var(--radius-md); }
/* The quiet history line — evidence, not navigation, so it reads as a
   footnote under the document rather than a version bar above it. */
.brief-history { margin-top: 20px; font-size: 13px; color: var(--text-secondary); }
.brief-history a, .brief-history-current { margin-left: 8px; white-space: nowrap; }
.brief-history-current { font-weight: 600; color: var(--text-primary); }
.brief-history .brief-kind { margin-left: 3px; }

/* Data Audit page furniture. The coverage table reuses the board's .designs
   styling; these are just its headings and spacing. */
.audit-head { margin: 24px 0 10px; }
.audit-head:first-child { margin-top: 0; }
.audit-head h2 { font-size: 17px; margin: 0 0 4px; }
.audit-table td, .audit-table th { vertical-align: top; }
.signoff-lead { margin: 0 0 20px; font-size: 14px; color: var(--text-secondary); }
.signoff-grid { display: grid; gap: 16px; }
.signoff-page .signoff-box { margin: 0; padding: 18px 20px; border-top: 0;
  background: var(--bg-primary); border: 1px solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-sm); }
.signoff-page .signoff-box h3 { font-size: 15px; margin: 0 0 10px; }
.signoff-page .signoff-box .btn-block { width: 100%; }
.signoff-page .signoff-final { border-color: var(--primary); }
.signoff-none { font-size: 13px; color: var(--text-muted); margin: 0; }

@media (max-width: 620px) {
  .review-tab { padding: 5px 12px; font-size: 12.5px; }
}

/* ------------------------------------------------------- progress overview */
.page-sub { color: var(--text-secondary); margin: -12px 0 24px; font-size: 14px; }
.progress-design { background: var(--bg-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: 18px 20px; margin-bottom: 18px;
  box-shadow: var(--shadow-sm); }
.progress-head { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.progress-head h2 { font-size: 17px; }
.progress-head a { color: inherit; text-decoration: none; }
.progress-head a:hover { color: var(--primary-dark); }
.progress-version { border-top: 1px solid var(--bg-tertiary); padding: 12px 0 4px; }
.progress-version-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 14px; }
.progress-version-head a { color: inherit; text-decoration: none; }
.progress-version-head a:hover { color: var(--primary-dark); }
.progress-people { list-style: none; margin: 10px 0 6px; padding: 0; font-size: 14px; }
.progress-people li { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 3px 0; }
.dot { width: 8px; height: 8px; border-radius: 50%; flex: none; position: relative; top: -1px; }
.dot-yes { background: var(--dot-yes); }
.dot-no { background: var(--danger); }
.dot-wait { background: var(--dot-wait); }
.progress-note { flex-basis: 100%; margin: 2px 0 0 16px; color: var(--text-secondary);
  font-size: 13px; }
.progress-meta { font-size: 13px; color: var(--text-secondary); margin: 6px 0 8px; }

/* --------------------------------------------------------- final sign-off */
.signoff-final { border-top: 2px solid var(--primary); }
.btn-final { background: var(--btn-final-bg); color: #ffffff; font-weight: 600;
  border-color: var(--btn-final-bg); }
.btn-final:hover { background: var(--btn-final-bg-hover); border-color: var(--btn-final-bg-hover); }
.modal-overlay { position: fixed; inset: 0; background: rgba(15, 23, 42, .55);
  display: flex; align-items: center; justify-content: center; z-index: 200; }
.modal-overlay.hidden { display: none; }
.modal { background: var(--bg-primary); border-radius: var(--radius-md);
  padding: 24px 26px; max-width: 420px; width: calc(100% - 40px);
  box-shadow: var(--shadow-lg); }
.modal h3 { font-size: 17px; margin-bottom: 10px; }
.modal p { font-size: 14px; color: var(--text-secondary); margin-bottom: 10px; }
.modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 16px; }
.link-danger { color: var(--danger); }
.link-danger:hover { color: var(--danger-hover); }

/* ------------------------------------------------------------------ briefs */
/* A brief is a document rendered in the app's own chrome, so it needs prose
   styling that nothing else here has: the rest of the app is tables, panels
   and cards. Tokens only - it inherits light/dark from :root like everything
   else, and carries no client palette (that is the sketch's alone). */
.brief-meta { color: var(--text-secondary); font-size: 14px; margin: -12px 0 18px; }
.brief-meta .tag { margin-left: 6px; }

.brief-versions { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; }
.brief-version { display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 12px; border: 1px solid var(--border); border-radius: var(--radius-md);
  font-size: 13px; color: var(--text-secondary); text-decoration: none; }
.brief-version:hover { border-color: var(--text-muted); }
.brief-version.is-active { border-color: var(--primary); color: var(--text-primary);
  font-weight: 600; }
.brief-kind { font-size: 10px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; padding: 2px 6px; border-radius: 4px; }
/* client = the baseline as sent (neutral, authoritative), scoped = our worked
   version (teal, i.e. Quanta's own). The colours carry the distinction the
   read-bar spells out. */
.brief-kind-client { background: var(--bg-elevated); color: var(--text-secondary); }
.brief-kind-scoped { background: var(--tint-info-bg); color: var(--tint-info-text); }

.brief-readbar { background: var(--bg-secondary); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 10px 14px; margin-bottom: 20px;
  font-size: 13px; color: var(--text-secondary); }

.brief-body { background: var(--bg-primary); border: 1px solid var(--border);
  border-radius: var(--radius-md); padding: 28px 32px; box-shadow: var(--shadow-panel);
  font-size: 15px; line-height: 1.65; color: var(--text-primary); }
.brief-body h1 { font-size: 22px; margin: 0 0 4px; letter-spacing: -0.01em; }
.brief-body h2 { font-size: 17px; margin: 28px 0 10px; padding-top: 18px;
  border-top: 1px solid var(--border-light); }
.brief-body h2:first-of-type { border-top: 0; padding-top: 0; }
.brief-body h3 { font-size: 14px; margin: 20px 0 8px; color: var(--text-secondary);
  text-transform: uppercase; letter-spacing: .04em; }
.brief-body p { margin: 0 0 12px; }
.brief-body ul, .brief-body ol { margin: 0 0 14px; padding-left: 22px; }
.brief-body li { margin-bottom: 6px; }
.brief-body li > ul, .brief-body li > ol { margin-top: 6px; }
.brief-body strong { color: var(--text-primary); font-weight: 600; }
.brief-body hr { border: 0; border-top: 1px solid var(--border); margin: 28px 0; }
/* The client's own words, quoted. Left rule rather than italics - some of
   these run to several lines and italic prose that long is hard to read. */
.brief-body blockquote { margin: 0 0 14px; padding: 2px 0 2px 16px;
  border-left: 3px solid var(--primary); color: var(--text-secondary); }
.brief-body blockquote p:last-child { margin-bottom: 0; }
.brief-body code { background: var(--bg-tertiary); border-radius: 4px;
  padding: 1px 5px; font-size: 13px; }
.brief-body table { border-collapse: collapse; width: 100%; margin: 0 0 16px;
  font-size: 14px; }
.brief-body th, .brief-body td { border: 1px solid var(--border);
  padding: 7px 10px; text-align: left; }
.brief-body th { background: var(--bg-secondary); font-weight: 600; }

.brief-designs { margin-top: 24px; background: var(--bg-secondary);
  border: 1px solid var(--border); border-radius: var(--radius-md);
  padding: 16px 20px; }
.brief-designs h2 { font-size: 15px; margin: 0 0 10px; }
.brief-designs ul { list-style: none; margin: 0; padding: 0; }
.brief-designs li { padding: 6px 0; border-top: 1px solid var(--border-light); }
.brief-designs li:first-child { border-top: 0; }
.brief-designs a { font-weight: 600; color: var(--text-primary); text-decoration: none; }
.brief-designs a:hover { text-decoration: underline; }

@media (max-width: 640px) {
  .brief-body { padding: 20px 18px; }
}

/* ==========================================================================
   Create Brief — the chooser modal and the questionnaire (migration 006)

   Reuses .modal-overlay/.modal from the sign-off flow rather than introducing
   a second dialog treatment. The form's own vocabulary is deliberately small:
   a section, a field, a repeater. Seventeen sections is a lot of page, so
   every rule here is about making it scannable rather than decorative.
   ========================================================================== */

.page-head { display: flex; align-items: center; justify-content: space-between;
  gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }
.page-head .page-title { margin-bottom: 0; }

.flashes { margin-bottom: 18px; }
.flash { background: var(--bg-secondary); border: 1px solid var(--border-strong);
  border-left: 3px solid var(--primary); border-radius: var(--radius-sm);
  padding: 12px 16px; margin: 0 0 8px; font-size: 14px; color: var(--text-primary); }

/* Amber, and it means "something needs your attention" - brief.html's comment
   already relies on that being true of .callout and reaches for a different
   panel for its neutral back-link. The class was in use with no rule behind
   it, so the pending sign-off block on the index rendered as bare text. */
.callout { background: var(--tint-warn-soft); border: 1px solid var(--tint-warn-line);
  border-radius: var(--radius-lg); padding: 18px 20px; margin-bottom: 20px; }
.callout h2 { font-size: 16px; margin-bottom: 10px; color: var(--tint-warn-strong); }
.callout ul { margin: 0 0 0 18px; font-size: 14px; color: var(--tint-warn-text); }
.callout-error { background: var(--tint-danger-bg); border-color: var(--tint-danger-line); }
.callout-error h2, .callout-error ul { color: var(--tint-danger-text); }

/* -- the chooser ---------------------------------------------------------- */
.modal-wide { max-width: 620px; }
/* auto-fit, not 1fr 1fr: the chooser renders brief_forms.FORM_CHOICES, so a
   third artefact type must not land as an orphan card on its own row. */
.kind-choices { display: grid; gap: 12px; margin-top: 16px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.kind-choice { display: flex; flex-direction: column; gap: 6px; padding: 18px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-md);
  text-decoration: none; color: inherit; background: var(--bg-secondary);
  transition: border-color .15s ease, transform .15s ease; }
.kind-choice:hover, .kind-choice:focus-visible { border-color: var(--primary);
  transform: translateY(-1px); outline: none; }
.kind-choice i { font-size: 20px; color: var(--primary); }
.kind-choice strong { font-size: 15px; }
.kind-choice span { font-size: 13px; color: var(--text-secondary); line-height: 1.45; }
/* The two capture methods inside a card — the card answers WHAT is being
   briefed, these answer HOW its brief gets captured. */
.kind-methods { display: flex; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.kind-methods .btn { font-size: 12.5px; }

/* -- the questionnaire ---------------------------------------------------- */
.brief-form { display: flex; flex-direction: column; gap: 14px; }
.qsection { background: var(--bg-primary); border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg); padding: 22px 24px; }
.qsection[hidden] { display: none; }
.qsection h2 { font-size: 17px; display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 8px; }
.qnum { display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 26px; border-radius: 50%; background: var(--bg-elevated);
  color: var(--text-secondary); font-size: 12px; font-weight: 600; }
/* The commentary from briefs/_TEMPLATE.md. It is the reason the section
   exists, which is what makes the answer good — so it is not small print. */
.qhelp { font-size: 13.5px; color: var(--text-secondary); line-height: 1.55;
  margin: 0 0 18px; max-width: 68ch; }

.qfield { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
.qfield > label { font-size: 14px; font-weight: 600; color: var(--text-primary); }
.fhelp { font-size: 12.5px; color: var(--text-secondary); margin: 0; max-width: 68ch;
  line-height: 1.5; }
.req { font-size: 11px; font-weight: 500; color: var(--text-muted);
  text-transform: uppercase; letter-spacing: .04em; margin-left: 6px; }
.qgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0 18px; }

.brief-form input[type="text"], .brief-form textarea, .brief-form select {
  font: inherit; font-size: 14px; padding: 9px 12px; width: 100%;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--bg-primary); color: var(--text-primary); }
.brief-form textarea { line-height: 1.55; resize: vertical; }
.brief-form textarea.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; }
.brief-form input:focus, .brief-form textarea:focus, .brief-form select:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(var(--primary-rgb), .12); }
.brief-form input[readonly] { background: var(--bg-tertiary); color: var(--text-secondary); }

/* -- client / scoped ------------------------------------------------------ */
.kind-toggle { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.kind-opt { display: grid; grid-template-columns: auto 1fr; gap: 4px 10px;
  align-items: baseline; padding: 12px 14px; border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm); cursor: pointer; }
.kind-opt:has(input:checked) { border-color: var(--primary);
  background: rgba(var(--primary-rgb), .04); }
.kind-opt input { grid-row: 1; }
.kind-opt strong { grid-row: 1; font-size: 14px; }
.kind-opt span { grid-column: 2; font-size: 12.5px; color: var(--text-secondary);
  line-height: 1.5; }

/* -- repeaters ------------------------------------------------------------ */
.rep { display: flex; flex-direction: column; gap: 8px; }
.rep-row { display: flex; gap: 10px; align-items: flex-end; }
.rep-line { align-items: center; }
.rep-cell { display: flex; flex-direction: column; gap: 4px; flex: 1 1 0; min-width: 0; }
.rep-narrow { flex: 1 1 120px; }
.rep-wide { flex: 2 1 220px; }
.rep-label { font-size: 11.5px; color: var(--text-secondary); font-weight: 500; }
/* Column headings on the first row only: the repeater is a table being edited,
   and repeating the header above every row turns four rows into forty lines. */
.rep-row:not(:first-child) .rep-label { display: none; }
.rep-drop { flex: 0 0 auto; width: 30px; height: 34px; border-radius: var(--radius-sm);
  border: 1px solid transparent; background: transparent; cursor: pointer;
  color: var(--text-muted); font-size: 18px; line-height: 1; }
.rep-drop:hover { color: var(--danger); border-color: var(--border-strong); }
.rep-add { align-self: flex-start; margin-top: 8px; font-size: 13px; padding: 6px 12px; }

.rep-stacked { gap: 14px; }
.rep-item { border: 1px solid var(--border-strong); border-left: 3px solid var(--primary);
  border-radius: var(--radius-sm); padding: 16px 18px 2px; background: var(--bg-secondary); }
.rep-item-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.rid { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  font-weight: 600; padding: 3px 8px; border-radius: var(--radius-sm);
  background: var(--bg-elevated); color: var(--text-secondary); }
.rep-item-head .rep-drop { margin-left: auto; }

.checklist { display: flex; flex-direction: column; gap: 8px; }
.check { display: flex; gap: 10px; align-items: baseline; font-size: 14px;
  color: var(--text-secondary); line-height: 1.5; }

.form-actions { display: flex; gap: 10px; justify-content: flex-end;
  padding: 4px 0 40px; }

@media (max-width: 720px) {
  .kind-choices, .kind-toggle { grid-template-columns: 1fr; }
  .rep-row { flex-wrap: wrap; }
  .rep-row .rep-label { display: block; }
  .qsection { padding: 18px 16px; }
}

/* ==========================================================================
   Cross-document view transitions — what makes moving between the review
   tabs read as flipping views of one page rather than loading another.

   Same-origin navigations get a short cross-fade; the topbar and the viewer
   bar are named as their own transition groups, so the chrome holds still
   while only the work underneath changes. Browsers without the at-rule
   (or users preferring reduced motion) just get the plain navigation.
   ========================================================================== */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: .16s; }
.topbar { view-transition-name: qd-topbar; }
.viewer-bar { view-transition-name: qd-viewerbar; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
