/* ==========================================================================
   Helpy — the console's design system
   --------------------------------------------------------------------------
   THIS FILE IS NOT THE CONVERSATION.

   The app has two skins and they never load together:

     static/style.css    the live conversation with the avatar (/,
                         /conversation/<token>, /call/<token>), plus the
                         pages a visitor sees instead of it when a link is
                         over. Owned by the stage. Do not restyle it from
                         here — nothing in this file reaches those pages,
                         and that is the point.

     static/console.css  THIS FILE: everything behind a sign-in that is not
                         the stage — /admin/…, /backoffice/…, /manager,
                         /partner, /avatar, and the account screens
                         (sign in, not invited, the consent screen).

   A console page links this file ONLY. That separation is deliberate: it
   means a change to a button, a table or a token here cannot move a single
   pixel of the conversation, however far this system grows.

   Layout:
     1. Tokens & base      — the vocabulary everything else is written in
     2. Backdrop swatches  — the one thing shared with the stage (see below)
     3. Primitives         — buttons, fields, tables, badges, cards
     4. The console        — shell, sidebar, page header
     5. Account screens    — sign-in, consent
     6. Avatar studio      — /avatar

   Rules of the house:
     · Nothing hard-codes a colour, a radius or a gap — everything comes from
       a token, so a rebrand is one block of this file and not a search
       across nine templates.
     · Layout belongs to a class, never to a style="" attribute. Pages and
       the JS that renders rows use the components below; if something needs
       a new shape, it gets a name here rather than an inline rule there.
     · Every interactive element has a visible :focus-visible ring. This is
       an internal console people work in all day with a keyboard.
   ========================================================================== */

:root {
  /* ---- Surfaces: a near-black neutral ramp, each step a real elevation ---- */
  --bg: #0a0d12;             /* the page itself */
  --surface: #111620;        /* cards, the sidebar */
  --surface-2: #161c27;      /* inputs, nested panels, table hover */
  --surface-3: #1d2532;      /* pressed / selected */
  --panel: var(--surface);   /* the names the copied backdrop rules below use */
  --panel-2: var(--surface-2);

  /* ---- Lines: two weights. Hairlines separate, strong lines enclose. ---- */
  --line: #212936;
  --line-strong: #2c3646;

  /* ---- Text ---- */
  --text: #e8edf5;
  --text-2: #b7c2d1;         /* secondary copy that still has to be read */
  --muted: #8593a6;          /* labels, metadata, hints */
  --text-inverse: #0a0d12;

  /* ---- Brand + semantics ---- */
  --accent: #5b8cff;
  --accent-2: #3f6fe8;       /* the pressed/filled variant */
  --accent-soft: rgba(91, 140, 255, .14);
  --accent-line: rgba(91, 140, 255, .42);
  --ok: #34d399;
  --ok-soft: rgba(52, 211, 153, .13);
  --warn: #f2b13c;
  --warn-soft: rgba(242, 177, 60, .13);
  --danger: #f4726a;
  --danger-soft: rgba(244, 114, 106, .13);
  --info: #6fb5ff;
  --info-soft: rgba(111, 181, 255, .13);

  /* ---- Type ---- */
  --font: "Inter", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "JetBrains Mono", Menlo, Consolas, monospace;
  --fs-xs: 11.5px;
  --fs-sm: 12.5px;
  --fs-md: 13.5px;
  --fs-lg: 15px;
  --fs-xl: 19px;
  --fs-2xl: 24px;

  /* ---- Space: a 4px grid. Gaps below are always one of these. ---- */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-10: 40px;

  /* ---- Radii ---- */
  --r-sm: 6px;
  --r-md: 9px;
  --r-lg: 14px;
  --r-xl: 18px;
  --r-pill: 999px;

  /* ---- Elevation: shadows that read as depth, not as glow ---- */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .35);
  --shadow-md: 0 6px 20px rgba(0, 0, 0, .32);
  --shadow-lg: 0 22px 60px rgba(0, 0, 0, .5);
  --ring: 0 0 0 3px rgba(91, 140, 255, .32);

  /* ---- Console geometry ---- */
  --sidebar-w: 264px;
  --topbar-h: 58px;
  --content-max: 1240px;
  --speed: .16s;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  min-height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-md);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--accent-soft); }

/* One focus treatment for the whole console. Mouse users never see it;
   keyboard users never lose their place. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* Scrollbars, so the sidebar and long tables don't hand the page back a
   chunk of Windows grey. */
* { scrollbar-color: var(--line-strong) transparent; scrollbar-width: thin; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb {
  background: var(--line-strong); border-radius: var(--r-pill);
  border: 3px solid transparent; background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: #3a4657; background-clip: content-box; }
*::-webkit-scrollbar-track { background: transparent; }

/* ==========================================================================
   2. BACKDROP SWATCHES
   --------------------------------------------------------------------------
   The block below is COPIED, unchanged, from the stage's own stylesheet
   (static/style.css). The Projects page shows each backdrop as a thumbnail,
   and the whole point of those thumbnails is that they are the real thing at
   a smaller size — so they have to be drawn by the same rules.

   It lives here rather than being shared because the console must be able to
   load without style.css: that is what guarantees this system can never
   disturb the conversation. style.css remains the ORIGINAL — if a backdrop
   is ever changed there, copy the change down here so the swatches keep
   telling the truth.
   ========================================================================== */

/* ==========================================================================
   Backdrops (.stage-bg-*)
   --------------------------------------------------------------------------
   What sits BEHIND the avatar. The WebGL canvas is drawn with alpha:true, so
   these CSS layers show through around her — no image files, nothing to
   download or host, and they stay sharp at any size.

   Each backdrop is built from the same three layers, so they all read as the
   same "room" photographed differently rather than as clip art:
     background  — the wall: a light source or two, plus a vertical wash
     ::before    — a soft blurred panel (a window / light bank) for depth
     ::after     — a floor/desk falloff grounding the bottom of the frame

   The set is the BACKGROUNDS catalog in app.py; a project picks one and it
   follows that project into any custom conversation it's attached to. The
   classes are deliberately not scoped to #stage so .bg-preview can wear them
   too (see the Projects page swatches).
   ========================================================================== */
[class*="stage-bg-"]::before,
[class*="stage-bg-"]::after {
  content: "";
  position: absolute;
  z-index: 0;
  pointer-events: none;
}
/* the light bank / window */
[class*="stage-bg-"]::before {
  right: 7%; top: 9%;
  width: 30%; height: 48%;
  border-radius: 14px;
  filter: blur(42px);
}
/* the floor */
[class*="stage-bg-"]::after {
  left: 0; right: 0; bottom: 0; height: 26%;
}

/* ---- Rooms: drawn scenes, one SVG each (static/backgrounds/) --------------
   Vector, so a 900px-tall artboard is still crisp on a 4K display at a few
   KB. They bring their own light and depth, so the shared blurred light
   panel is switched off over them — it would sit on the picture like a
   smudge — and only a soft floor shadow is kept, to seat the avatar and to
   hold contrast under the Talk button. */
.stage-bg-office,
.stage-bg-bright,
.stage-bg-boardroom2,
.stage-bg-library,
.stage-bg-custom {
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
  background-color: #1b1f26;    /* shows only while the image is still loading */
}
.stage-bg-office::before,
.stage-bg-bright::before,
.stage-bg-boardroom2::before,
.stage-bg-library::before,
.stage-bg-custom::before { display: none; }
.stage-bg-office::after,
.stage-bg-bright::after,
.stage-bg-boardroom2::after,
.stage-bg-library::after,
.stage-bg-custom::after {
  height: 34%;
  background: linear-gradient(180deg, transparent, rgba(10, 13, 18, 0.5));
}
.stage-bg-bright::after {
  background: linear-gradient(180deg, transparent, rgba(70, 82, 98, 0.42));
}

.stage-bg-office { background-image: url("backgrounds/office-garden.svg"); }
.stage-bg-bright { background-image: url("backgrounds/bright-office.svg"); }
.stage-bg-boardroom2 { background-image: url("backgrounds/boardroom-city.svg"); }
.stage-bg-library { background-image: url("backgrounds/library.svg"); }
/* .stage-bg-custom's image is the owner's upload, set inline on #stage —
   see _apply_project_look() and index.html. */

/* None — the plain studio look this app has always had. Not the absence of a
   backdrop, just the default one. */
.stage-bg-none {
  background:
    radial-gradient(55% 50% at 80% 18%, rgba(255, 240, 214, 0.22), transparent 60%),
    radial-gradient(45% 45% at 18% 26%, rgba(150, 178, 214, 0.14), transparent 62%),
    linear-gradient(180deg, #313b49 0%, #2a3340 42%, #20262f 68%, #161b22 100%);
}
.stage-bg-none::before {
  background: linear-gradient(135deg, rgba(255, 250, 240, 0.20), rgba(190, 214, 255, 0.05));
}
.stage-bg-none::after {
  background: linear-gradient(180deg, transparent, rgba(10, 13, 18, 0.55));
}

/* Photo studio — a seamless grey sweep with the subject lit from front-left.
   The safest backdrop for a headshot: neutral, no colour cast on skin. */
.stage-bg-studio {
  background:
    radial-gradient(62% 58% at 42% 30%, rgba(255, 255, 255, 0.30), transparent 66%),
    radial-gradient(70% 60% at 50% 108%, rgba(0, 0, 0, 0.28), transparent 60%),
    linear-gradient(180deg, #8d949c 0%, #7b838c 46%, #626a73 74%, #4a5158 100%);
}
.stage-bg-studio::before {
  right: 10%; top: 6%; width: 34%; height: 40%;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.30), rgba(255, 255, 255, 0.04));
}
.stage-bg-studio::after {
  height: 30%;
  background: linear-gradient(180deg, transparent, rgba(38, 43, 48, 0.55));
}

/* Corporate navy — keynote-stage blue with a single soft spotlight. */
.stage-bg-navy {
  background:
    radial-gradient(58% 52% at 50% 22%, rgba(120, 165, 235, 0.26), transparent 64%),
    radial-gradient(40% 40% at 12% 70%, rgba(56, 96, 168, 0.18), transparent 66%),
    linear-gradient(180deg, #1c2c4a 0%, #17243c 44%, #101a2c 72%, #0a1020 100%);
}
.stage-bg-navy::before {
  right: 8%; top: 12%; width: 26%; height: 44%;
  background: linear-gradient(135deg, rgba(160, 200, 255, 0.22), rgba(80, 130, 210, 0.04));
}
.stage-bg-navy::after {
  background: linear-gradient(180deg, transparent, rgba(4, 8, 16, 0.62));
}

/* Boardroom — warm walnut panelling, daylight coming in from the right. */
.stage-bg-boardroom {
  background:
    radial-gradient(52% 48% at 84% 20%, rgba(255, 226, 178, 0.30), transparent 62%),
    radial-gradient(46% 44% at 20% 40%, rgba(120, 78, 44, 0.22), transparent 66%),
    /* panel seams: a lit edge then a shadowed groove, every 96px — subtle at
       full size, but enough that it reads as panelling and not flat paint */
    repeating-linear-gradient(90deg,
      rgba(255, 234, 200, 0.05) 0 1px,
      rgba(0, 0, 0, 0.13) 1px 4px,
      transparent 4px 96px),
    linear-gradient(180deg, #6a4a30 0%, #573a25 40%, #3f2a1b 70%, #241811 100%);
}
.stage-bg-boardroom::before {
  right: 5%; top: 8%; width: 30%; height: 52%;
  background: linear-gradient(135deg, rgba(255, 242, 214, 0.28), rgba(255, 214, 150, 0.05));
}
.stage-bg-boardroom::after {
  height: 24%;
  background: linear-gradient(180deg, transparent, rgba(28, 18, 12, 0.66));
}

/* Daylight office — bright and airy, big window on the right. Light enough
   that the on-stage text needs darkening; see the overrides below. */
.stage-bg-daylight {
  background:
    /* kept off full white: the avatar's shoulder sits under this corner and
       blows out against a pure-white window */
    radial-gradient(60% 56% at 78% 16%, rgba(255, 255, 255, 0.58), transparent 62%),
    radial-gradient(48% 46% at 16% 34%, rgba(206, 224, 244, 0.55), transparent 66%),
    linear-gradient(180deg, #e6ecf4 0%, #dae2ec 44%, #c6d1de 74%, #adbaca 100%);
}
.stage-bg-daylight::before {
  right: 6%; top: 7%; width: 32%; height: 50%;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.70), rgba(214, 232, 255, 0.30));
}
.stage-bg-daylight::after {
  height: 28%;
  background: linear-gradient(180deg, transparent, rgba(120, 136, 158, 0.42));
}

/* Graphite — near-black and minimal, one low spotlight. Premium/product. */
.stage-bg-graphite {
  background:
    radial-gradient(50% 46% at 50% 26%, rgba(226, 232, 240, 0.16), transparent 64%),
    linear-gradient(180deg, #23262b 0%, #1a1d21 46%, #121417 74%, #0a0b0d 100%);
}
.stage-bg-graphite::before {
  right: 12%; top: 10%; width: 24%; height: 40%;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.02));
}
.stage-bg-graphite::after {
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.6));
}

/* Emerald — deep green with a warm key light. Reads well on brand decks. */
.stage-bg-emerald {
  background:
    radial-gradient(56% 50% at 72% 20%, rgba(212, 240, 214, 0.22), transparent 62%),
    radial-gradient(44% 42% at 18% 52%, rgba(20, 110, 84, 0.26), transparent 66%),
    linear-gradient(180deg, #1c4339 0%, #16362f 44%, #102621 72%, #08150f 100%);
}
.stage-bg-emerald::before {
  right: 9%; top: 10%; width: 28%; height: 46%;
  background: linear-gradient(135deg, rgba(226, 255, 238, 0.20), rgba(90, 190, 150, 0.05));
}
.stage-bg-emerald::after {
  background: linear-gradient(180deg, transparent, rgba(4, 14, 10, 0.62));
}

/* Backdrop swatches on the Projects page — the same .stage-bg-* classes at
   thumbnail size, so what you pick is literally what the stage will look
   like rather than an approximation of it. */
.bg-swatches {
  display: grid; gap: 10px; margin-top: 10px;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
}
.bg-swatch {
  flex: none; display: block; width: 100%; padding: 6px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 10px;
  cursor: pointer; text-align: center;
}
.bg-swatch.selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.bg-preview {
  position: relative; overflow: hidden; display: block;
  width: 100%; height: 58px; border-radius: 6px;
}
/* The full-size backdrop blurs its light panel by 42px, which at thumbnail
   scale would smear over the whole swatch — scale the blur down with it. */
.bg-preview::before { filter: blur(11px); }
.bg-swatch-label {
  display: block; margin-top: 6px;
  font-size: 11px; font-weight: 600; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bg-swatch.selected .bg-swatch-label { color: var(--text); }

/* The uploaded shirt logo, shown against a mid grey — a logo is often white
   or dark, and either would vanish on a panel of the other. */
.logo-preview {
  flex: none; width: 66px; height: 66px; border-radius: 10px;
  background: #6b7280 center / contain no-repeat;
  border: 1px solid var(--line);
}
.logo-preview.hidden { display: none; }

/* ==========================================================================
   3. PRIMITIVES
   --------------------------------------------------------------------------
   The small vocabulary every page and every JS-rendered row is built from.
   ========================================================================== */

/* ---- Type ---------------------------------------------------------------- */
h1, h2, h3, h4 { margin: 0; font-weight: 650; letter-spacing: -.01em; line-height: 1.25; }
h1 { font-size: var(--fs-2xl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }
h4 { font-size: var(--fs-md); }

p { margin: 0 0 var(--sp-3); }
p:last-child { margin-bottom: 0; }

a { color: var(--accent); }

.sub { color: var(--text-2); margin: 0 0 var(--sp-4); font-size: var(--fs-md); line-height: 1.6; max-width: 78ch; }
.hint { color: var(--muted); font-size: var(--fs-sm); line-height: 1.6; margin: var(--sp-2) 0 0; max-width: 86ch; }
.hint.err { color: var(--danger); }
.muted { color: var(--muted); }
.mono { font-family: var(--font-mono); font-size: var(--fs-sm); }
.hidden { display: none !important; }
.wide { width: 100%; }
.num { font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap; }

.section-title { font-size: var(--fs-lg); margin: var(--sp-8) 0 var(--sp-3); }

.ghost-link {
  color: var(--accent); font-size: var(--fs-sm); font-weight: 600; text-decoration: none;
}
.ghost-link:hover { text-decoration: underline; }

/* ---- Layout helpers ------------------------------------------------------ */
.row { display: flex; gap: var(--sp-3); }
.row.wrap { flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }
.spacer { flex: 1 1 auto; }

/* ---- Buttons -------------------------------------------------------------
   The default button is the SECONDARY one: enterprise screens are mostly rows
   of equal, undramatic actions, and a page where six buttons are all blue has
   told the reader nothing. `.primary` marks the single action a page exists
   for; `.danger` marks the one that can't be undone.

   Buttons are content-sized. They only stretch when told to (`.grow`), which
   is why no caller needs style="flex:none" any more. */
button, .btn {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: 36px; padding: 0 var(--sp-4);
  border: 1px solid var(--line-strong); border-radius: var(--r-md);
  background: var(--surface-2); color: var(--text);
  font-family: inherit; font-size: var(--fs-md); font-weight: 600; line-height: 1;
  white-space: nowrap; cursor: pointer;
  transition: background var(--speed) ease, border-color var(--speed) ease, color var(--speed) ease;
}
button:hover, .btn:hover { background: var(--surface-3); border-color: #3b4759; }
button:active, .btn:active { background: var(--surface-3); transform: translateY(.5px); }

button.primary, .btn.primary {
  background: var(--accent-2); border-color: var(--accent-2); color: #fff;
  box-shadow: var(--shadow-sm);
}
button.primary:hover, .btn.primary:hover { background: var(--accent); border-color: var(--accent); }

button.danger, .btn.danger { color: var(--danger); border-color: rgba(244, 114, 106, .38); background: var(--danger-soft); }
button.danger:hover, .btn.danger:hover { background: rgba(244, 114, 106, .2); border-color: var(--danger); }

/* Quiet action inside a dense row — a table cell, a card header. */
button.ghost, .btn.ghost { background: transparent; border-color: transparent; color: var(--text-2); }
button.ghost:hover, .btn.ghost:hover { background: var(--surface-2); border-color: var(--line); color: var(--text); }

button.small, .btn.small { min-height: 30px; padding: 0 var(--sp-3); font-size: var(--fs-sm); }
button.icon, .btn.icon { min-height: 30px; width: 30px; padding: 0; font-size: var(--fs-md); }

button:disabled, .btn.disabled { opacity: .45; cursor: not-allowed; }
button:disabled:hover { background: var(--surface-2); border-color: var(--line-strong); }

/* A row of buttons. Actions that belong together sit together; anything with
   `.push` is shoved to the far end (delete, usually). */
.btn-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center; }
.btn-row .push { margin-left: auto; }
.btns { margin: var(--sp-2) 0 var(--sp-1); }

/* ---- Fields --------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-4); min-width: 0; }
.field > span {
  font-size: var(--fs-sm); color: var(--text-2); font-weight: 600; letter-spacing: .01em;
  display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap;
}
.field > span small { color: var(--muted); font-weight: 500; }
.field > span small.ok { color: var(--ok); font-weight: 600; }
.field.grow { flex: 1 1 220px; }
.field .hint { margin-top: var(--sp-1); }

textarea, input[type="text"], input[type="email"], input[type="url"],
input[type="password"], input[type="number"], input[type="search"], select {
  width: 100%;
  min-height: 38px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  color: var(--text);
  border-radius: var(--r-md);
  padding: 8px 12px;
  font-size: var(--fs-md); font-family: inherit; line-height: 1.4;
  outline: none;
  transition: border-color var(--speed) ease, box-shadow var(--speed) ease, background var(--speed) ease;
}
textarea { min-height: 76px; resize: vertical; line-height: 1.6; }
input::placeholder, textarea::placeholder { color: #667586; }
textarea:hover, input:hover, select:hover { border-color: #3b4759; }
textarea:focus, input:focus, select:focus {
  border-color: var(--accent); box-shadow: var(--ring); background: var(--surface-2);
}
input:disabled, select:disabled, textarea:disabled { opacity: .5; cursor: not-allowed; }

/* Native select needs its own chevron once the OS one stops matching. */
select {
  appearance: none; -webkit-appearance: none;
  padding-right: 34px;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 17px) 52%, calc(100% - 12px) 52%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
select option { background: var(--surface); color: var(--text); }

input[type="file"] {
  width: 100%; min-height: 38px; padding: 6px 10px;
  background: var(--surface-2); border: 1px dashed var(--line-strong);
  border-radius: var(--r-md); color: var(--text-2); font-size: var(--fs-sm); font-family: inherit;
}
input[type="file"]::file-selector-button {
  margin-right: var(--sp-3); padding: 5px 12px;
  border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  background: var(--surface-3); color: var(--text);
  font: inherit; font-size: var(--fs-sm); font-weight: 600; cursor: pointer;
}
input[type="file"]:hover { border-color: var(--accent-line); }

input[type="color"] {
  width: 54px; height: 36px; padding: 2px; cursor: pointer;
  background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: var(--r-md);
}
input[type="checkbox"], input[type="radio"] { width: auto; min-height: 0; accent-color: var(--accent); cursor: pointer; }
input[type="range"] { width: 100%; accent-color: var(--accent); }
.sliders span b { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; }

/* A checkbox and its label, as one clickable line. */
.check, .check-row {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-md); font-weight: 500; cursor: pointer;
}
.check { margin-bottom: var(--sp-2); }
.check-row + .hint { margin-top: var(--sp-2); }
.check-list { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-5); }

/* Fields laid side by side above a table — the "create something" toolbar. */
.toolbar {
  display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: flex-end;
}
.toolbar .field { margin-bottom: 0; }
.invite-row { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: flex-end; }
.invite-row .field { margin-bottom: 0; }

.form-grid {
  display: grid; gap: var(--sp-4);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.form-grid .field { margin-bottom: 0; }

/* Two-way toggle (e.g. batch vs real-time response mode) */
.segmented {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: var(--r-md);
}
.seg-btn {
  flex: 1 1 auto; min-height: 30px; padding: 0 var(--sp-4);
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: transparent; color: var(--muted);
  font-size: var(--fs-sm); font-weight: 600; font-family: inherit; cursor: pointer;
  transition: var(--speed);
}
.seg-btn:hover { color: var(--text); background: var(--surface-3); }
.seg-btn.active { background: var(--accent-2); border-color: var(--accent-2); color: #fff; }

.adv {
  margin: var(--sp-2) 0; padding: var(--sp-3) var(--sp-4);
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-2);
}
.adv summary {
  cursor: pointer; color: var(--text-2); font-size: var(--fs-md); font-weight: 600;
  list-style: none; display: flex; align-items: center; gap: var(--sp-2);
}
.adv summary::-webkit-details-marker { display: none; }
.adv summary::before { content: "▸"; color: var(--muted); transition: transform var(--speed) ease; }
.adv[open] summary::before { transform: rotate(90deg); }
.adv[open] summary { margin-bottom: var(--sp-4); }
.adv .field:last-of-type { margin-bottom: var(--sp-3); }

/* ---- Status line ---------------------------------------------------------
   Every page has exactly one of these under its form. It is empty most of the
   time, so it must take up no room when it has nothing to say. */
.status {
  color: var(--text-2); font-size: var(--fs-sm); margin: var(--sp-3) 0 0;
  display: flex; align-items: center; gap: var(--sp-2);
}
.status:empty { display: none; }
.status::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: var(--ok); flex: none;
}
.status.err { color: var(--danger); }
.status.err::before { background: var(--danger); }

/* ---- Badges --------------------------------------------------------------
   One shape for every state word in the product: enabled, live, revoked,
   billed-to, "not tested yet". A status that is a bare string in a cell reads
   as data; the same word in a badge reads as a state. */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: var(--r-pill);
  background: var(--surface-3); border: 1px solid var(--line-strong);
  color: var(--text-2); font-size: var(--fs-xs); font-weight: 650;
  letter-spacing: .02em; white-space: nowrap; line-height: 1.5;
}
.badge::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; opacity: .9; flex: none;
}
.badge.no-dot::before { display: none; }
.badge--ok { color: var(--ok); background: var(--ok-soft); border-color: rgba(52, 211, 153, .3); }
.badge--live { color: var(--ok); background: var(--ok-soft); border-color: rgba(52, 211, 153, .3); }
.badge--live::before { animation: badgePulse 1.8s ease-out infinite; }
.badge--warn { color: var(--warn); background: var(--warn-soft); border-color: rgba(242, 177, 60, .3); }
.badge--danger { color: var(--danger); background: var(--danger-soft); border-color: rgba(244, 114, 106, .32); }
.badge--info { color: var(--info); background: var(--info-soft); border-color: rgba(111, 181, 255, .3); }
.badge--accent { color: var(--accent); background: var(--accent-soft); border-color: var(--accent-line); }
.badge--muted { color: var(--muted); }
@keyframes badgePulse {
  0%   { box-shadow: 0 0 0 0 rgba(52, 211, 153, .5); }
  70%  { box-shadow: 0 0 0 5px rgba(52, 211, 153, 0); }
  100% { box-shadow: 0 0 0 0 rgba(52, 211, 153, 0); }
}

/* A neutral fact, not a state: a client id, a key prefix, a count. */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: var(--r-sm);
  background: var(--surface-2); border: 1px solid var(--line);
  color: var(--muted); font-size: var(--fs-xs); font-weight: 600; white-space: nowrap;
}
.chip.mono { font-family: var(--font-mono); }

/* ---- Cards ---------------------------------------------------------------
   `.card` and `.tcard` are the same object; `.tcard` is kept because the
   avatar studio and a lot of rendered rows already ask for it by that name. */
.card, .tcard {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--sp-5);
  box-shadow: var(--shadow-sm);
}
.card + .card, .tcard + .tcard { margin-top: var(--sp-4); }

.card-head {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  margin: 0 0 var(--sp-4); padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--line);
}
.card-head.plain { border-bottom: 0; padding-bottom: 0; }
.card-head > .grow { min-width: 0; }
.card-title { font-size: var(--fs-lg); font-weight: 650; margin: 0; }
.card-desc { color: var(--muted); font-size: var(--fs-sm); margin: var(--sp-1) 0 0; max-width: 86ch; line-height: 1.6; }
.card-actions { display: flex; gap: var(--sp-2); align-items: center; margin-left: auto; flex: none; }
.card-foot {
  margin-top: var(--sp-4); padding-top: var(--sp-4); border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: var(--sp-2); align-items: center;
}

/* Cards in the studio and in older markup put their title in an <h3> with a
   trailing <small> explanation. Keep that shape working. */
.tcard h3 {
  margin: 0 0 var(--sp-4); font-size: var(--fs-lg); color: var(--text);
  display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap;
}
.tcard h3 small { color: var(--muted); font-size: var(--fs-sm); font-weight: 500; }

/* ---- Record rows ---------------------------------------------------------
   A list of things you open: projects, connectors, API clients. Clickable
   across its whole width, with the identity on the left, the facts under it
   and the affordance on the right. */
.list-row {
  display: flex; align-items: center; gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  transition: border-color var(--speed) ease, background var(--speed) ease;
}
.list-row + .list-row { margin-top: var(--sp-3); }
.list-row.clickable { cursor: pointer; }
.list-row.clickable:hover { border-color: var(--accent-line); background: var(--surface-2); }
.list-row-main { flex: 1 1 auto; min-width: 0; }
.list-row-title {
  display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  font-size: var(--fs-lg); font-weight: 650;
}
.list-row-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-4);
  margin: var(--sp-2) 0 0; color: var(--muted); font-size: var(--fs-sm);
}
.list-row-go { flex: none; color: var(--muted); font-size: var(--fs-sm); font-weight: 600; }
.list-row.clickable:hover .list-row-go { color: var(--accent); }

/* A metadata line: values separated by space, never by punctuation that
   wraps to the start of a line on its own. */
.meta-list {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1) var(--sp-4);
  margin: 0; color: var(--muted); font-size: var(--fs-sm);
}

/* ---- Tables --------------------------------------------------------------- */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.data-table { width: 100%; border-collapse: collapse; font-size: var(--fs-md); }
.data-table th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; color: var(--muted); font-weight: 650;
  font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .06em;
  padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2);
  border-bottom: 1px solid var(--line-strong);
  white-space: nowrap;
}
.data-table td {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
  white-space: nowrap;
}
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table tbody tr { transition: background var(--speed) ease; }
.data-table tbody tr:hover { background: var(--surface-2); }
.data-table td .hint, .data-table td .wrap { white-space: normal; }
.data-table td.wrap { white-space: normal; min-width: 220px; }
/* Controls inside a cell are one size smaller — a table is dense by design. */
.data-table select, .data-table input[type="number"], .data-table input[type="text"] {
  min-height: 32px; padding: 4px 10px; font-size: var(--fs-sm);
}
.data-table select { padding-right: 30px; }
.data-table button { min-height: 30px; padding: 0 var(--sp-3); font-size: var(--fs-sm); }
.data-table .t-actions { display: flex; gap: 6px; justify-content: flex-end; }
.data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
/* The expanded editor a row can open under itself. */
.data-table tr.row-editor > td { background: var(--surface-2); padding: var(--sp-4); }
.data-table tr.row-editor:hover > td { background: var(--surface-2); }

/* A URL in a narrow column must be cut with an ellipsis, never broken every
   few characters — that turns one row into a paragraph and the table into a
   wall. The full value stays available on hover and by copy. */
.cell-url {
  display: inline-block; max-width: 260px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom;
  font-family: var(--font-mono); font-size: var(--fs-sm);
}

/* ---- Empty states --------------------------------------------------------
   "Nothing here" is a screen state, not a grey sentence at the bottom of a
   table. */
.empty-state {
  display: flex; flex-direction: column; align-items: center; gap: var(--sp-2);
  padding: var(--sp-10) var(--sp-5);
  color: var(--muted); font-size: var(--fs-md); text-align: center;
}
.empty-state strong { color: var(--text-2); font-size: var(--fs-lg); font-weight: 650; }
.empty-state .hint { margin: 0; max-width: 46ch; }

/* ---- Callouts ------------------------------------------------------------
   Operator-facing notices: a missing key, a one-time secret, a scope warning.
   `.setup` is the legacy name for the same object. */
.callout, .setup {
  display: block;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--muted);
  border-radius: var(--r-md);
  padding: var(--sp-4) var(--sp-5);
  margin: 0 0 var(--sp-4);
  font-size: var(--fs-md); line-height: 1.6;
}
.callout > b:first-child, .setup > b:first-child {
  display: block; margin-bottom: var(--sp-2); color: var(--text); font-size: var(--fs-md);
}
.callout ol, .callout ul, .setup ol, .setup ul { margin: var(--sp-2) 0 0; padding-left: var(--sp-5); }
.callout li, .setup li { margin-bottom: var(--sp-1); }
.callout .hint, .setup .hint { margin-top: var(--sp-2); }
.callout--warn, .setup { border-left-color: var(--warn); }
.callout--danger { border-left-color: var(--danger); }
.callout--info { border-left-color: var(--info); }
.callout--accent { border-left-color: var(--accent); }

/* The one moment an API key is readable. Loud on purpose. */
#key-reveal { border-left-color: var(--accent); }
#key-value {
  margin: var(--sp-3) 0; padding: var(--sp-3) var(--sp-4);
  background: var(--bg); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  word-break: break-all; font-family: var(--font-mono); font-size: var(--fs-md); color: var(--accent);
}

/* Preformatted output — a connector test result, a payload sample. */
.code-block {
  margin: var(--sp-3) 0 0; padding: var(--sp-4);
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-md);
  font-family: var(--font-mono); font-size: var(--fs-sm); line-height: 1.6;
  white-space: pre-wrap; word-break: break-word; max-height: 340px; overflow: auto;
  color: var(--text-2);
}

/* ---- Stat tiles ---------------------------------------------------------- */
.stat-row {
  display: grid; gap: var(--sp-3); margin: 0 0 var(--sp-5);
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.stat-tile {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: var(--sp-4) var(--sp-5);
  display: flex; flex-direction: column; gap: var(--sp-1);
  box-shadow: var(--shadow-sm);
}
.stat-label {
  color: var(--muted); font-size: var(--fs-xs); font-weight: 650;
  text-transform: uppercase; letter-spacing: .06em; order: -1;
}
.stat-num { font-size: 27px; font-weight: 680; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.stat-tile.accent .stat-num { color: var(--accent); }
.stat-tile.ok .stat-num { color: var(--ok); }

/* ==========================================================================
   4. THE CONSOLE  (/admin/…, /backoffice/…, /manager, /partner)
   --------------------------------------------------------------------------
   A fixed sidebar for where you are in the product, a sticky top bar for what
   this page is and what you can do from it, and one scrolling column of
   content in the middle. The same shell on every page, so nothing about the
   navigation moves when you go from Users to Projects.
   ========================================================================== */
.app-shell { display: flex; min-height: 100vh; }

/* ---- Sidebar -------------------------------------------------------------- */
.sidebar {
  position: fixed; inset: 0 auto 0 0; z-index: 40;
  width: var(--sidebar-w); flex: none;
  display: flex; flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--line);
}
.sidebar-brand {
  display: flex; align-items: center; gap: var(--sp-3);
  height: var(--topbar-h); flex: none;
  padding: 0 var(--sp-5);
  border-bottom: 1px solid var(--line);
  color: var(--text); text-decoration: none;
}
.brand-mark {
  width: 28px; height: 28px; flex: none; border-radius: 8px;
  display: grid; place-items: center;
  background: linear-gradient(145deg, var(--accent), #7f5bff);
  color: #fff; font-size: 14px; font-weight: 800; letter-spacing: -.02em;
  box-shadow: 0 2px 10px rgba(91, 140, 255, .35);
}
.brand-text { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.brand-name { font-size: var(--fs-lg); font-weight: 700; letter-spacing: -.01em; }
.brand-sub { font-size: 10.5px; font-weight: 650; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }

.sidebar-nav { flex: 1 1 auto; overflow-y: auto; padding: var(--sp-5) var(--sp-3); }
.nav-section + .nav-section { margin-top: var(--sp-6); }
.nav-label {
  padding: 0 var(--sp-3) var(--sp-2);
  font-size: 10.5px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: #6b7889;
}
.nav-link {
  position: relative;
  display: flex; align-items: center; gap: var(--sp-3);
  padding: 8px var(--sp-3); margin-bottom: 2px;
  border-radius: var(--r-md);
  color: var(--text-2); font-size: var(--fs-md); font-weight: 550; text-decoration: none;
  transition: background var(--speed) ease, color var(--speed) ease;
}
.nav-link:hover { background: var(--surface-2); color: var(--text); }
.nav-link.active { background: var(--accent-soft); color: #cddcff; font-weight: 650; }
.nav-link.active::before {
  content: ""; position: absolute; left: -12px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 18px; border-radius: 0 3px 3px 0; background: var(--accent);
}
.nav-icon { width: 18px; text-align: center; font-size: 14px; flex: none; opacity: .9; }
.nav-link .badge { margin-left: auto; }
.nav-ext { margin-left: auto; color: var(--muted); font-size: var(--fs-sm); }

.sidebar-foot { flex: none; padding: var(--sp-3); border-top: 1px solid var(--line); }
.user-chip {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md);
  background: var(--surface-2); border: 1px solid var(--line);
}
.user-avatar {
  width: 30px; height: 30px; flex: none; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-3); border: 1px solid var(--line-strong);
  color: var(--text-2); font-size: var(--fs-sm); font-weight: 700; text-transform: uppercase;
}
.user-meta { min-width: 0; flex: 1 1 auto; line-height: 1.3; }
.user-name {
  font-size: var(--fs-sm); font-weight: 650; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.user-role { font-size: var(--fs-xs); color: var(--muted); text-transform: capitalize; }
.sign-out {
  flex: none; width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: var(--r-sm); color: var(--muted); text-decoration: none; font-size: 14px;
  transition: var(--speed);
}
.sign-out:hover { background: var(--surface-3); color: var(--danger); }

/* ---- Main column ---------------------------------------------------------- */
.app-main {
  flex: 1 1 auto; min-width: 0;
  margin-left: var(--sidebar-w);
  display: flex; flex-direction: column;
}
.app-topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: var(--sp-3);
  height: var(--topbar-h); flex: none;
  padding: 0 var(--sp-6);
  background: rgba(10, 13, 18, .82);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}
.crumbs {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); color: var(--muted); min-width: 0;
}
.crumbs .sep { opacity: .5; }
.crumbs strong { color: var(--text); font-weight: 650; font-size: var(--fs-md); }
.topbar-actions { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
.topbar-actions .ghost-link {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px var(--sp-3); border-radius: var(--r-md);
  color: var(--text-2); text-decoration: none;
  border: 1px solid transparent;
}
.topbar-actions .ghost-link:hover {
  background: var(--surface-2); border-color: var(--line); color: var(--text); text-decoration: none;
}

/* The hamburger only exists below the sidebar breakpoint. */
.nav-toggle { display: none; }
.nav-scrim { display: none; }

.page {
  width: 100%; max-width: var(--content-max);
  margin: 0 auto; padding: var(--sp-6) var(--sp-6) var(--sp-10);
  flex: 1 1 auto;
}
.page-head { margin-bottom: var(--sp-6); }
.page-head-row { display: flex; align-items: flex-start; gap: var(--sp-4); flex-wrap: wrap; }
.page-title { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--fs-2xl); }
.page-title .page-icon { font-size: 20px; opacity: .95; }
.page-lede { color: var(--text-2); font-size: var(--fs-md); line-height: 1.65; margin: var(--sp-3) 0 0; max-width: 82ch; }
.page-lede + .page-lede { margin-top: var(--sp-2); }
.page-actions { display: flex; gap: var(--sp-2); align-items: center; margin-left: auto; flex: none; }

.page-section { margin-top: var(--sp-6); }
.page-section:first-of-type { margin-top: 0; }
.section-head {
  display: flex; align-items: flex-start; gap: var(--sp-3); flex-wrap: wrap;
  margin-bottom: var(--sp-4);
}
.section-head .grow { min-width: 0; }
.section-head h2, .section-head h3 { font-size: var(--fs-lg); }
.section-head .hint { margin-top: var(--sp-1); }

/* A number the page keeps live in its own header (credit left, minutes). */
.metric-inline {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 4px 10px; border-radius: var(--r-md);
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  color: var(--accent); font-weight: 650; font-size: var(--fs-sm);
}

@media (max-width: 1000px) {
  :root { --content-max: 100%; }
  .sidebar {
    transform: translateX(-100%);
    transition: transform .22s ease;
    box-shadow: var(--shadow-lg);
  }
  body.nav-open .sidebar { transform: none; }
  .app-main { margin-left: 0; }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; min-height: 34px; padding: 0; flex: none;
  }
  body.nav-open .nav-scrim {
    display: block; position: fixed; inset: 0; z-index: 35;
    background: rgba(4, 6, 10, .6);
  }
  .page { padding: var(--sp-5) var(--sp-4) var(--sp-8); }
  .app-topbar { padding: 0 var(--sp-4); }
  .topbar-actions .ghost-link span.label { display: none; }
}

/* ---- Backoffice: panels that only matter to the built-in assistant --------
   A project answering from its owner's own chat API gets its context from
   that system, so the PDF and notes cards reach nothing. Dimmed and labelled
   rather than hidden: the material stays on file (and comes straight back if
   the project is switched to the built-in assistant again), it just isn't
   pretending to be in use. Inputs are genuinely disabled by the page too —
   this is the visual half of that, not the whole of it. */
.brain-off-note { display: none; }
.brain-dependent.brain-off { opacity: .6; }
.brain-dependent.brain-off .brain-off-note {
  display: flex; align-items: center; gap: var(--sp-2);
  margin: 0 0 var(--sp-4); padding: var(--sp-2) var(--sp-3);
  background: var(--warn-soft); border: 1px solid rgba(242, 177, 60, .28);
  border-radius: var(--r-sm); color: var(--warn);
}

/* ---- Admin > Avatar API: one card per API client -------------------------
   A partner row carries a lot: identity, three settings and four actions.
   Cramming them onto one flex line collapses the text column to nothing and
   wraps the metadata one word per line, so it stacks instead: identity, then
   facts, then controls that wrap as a group. */
.partner-card { display: flex; flex-direction: column; gap: var(--sp-4); }
.pc-head { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.pc-head strong { font-size: var(--fs-lg); font-weight: 650; }
.pc-meta { margin: 0; }
.pc-controls {
  display: flex; flex-wrap: wrap; gap: var(--sp-4);
  align-items: flex-end;
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
}
.pc-controls .field { flex: 1 1 210px; max-width: 280px; margin: 0; }
.pc-actions { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-left: auto; align-items: center; }

/* ---- Notes list (project detail) ----------------------------------------- */
.note-item {
  display: flex; align-items: flex-start; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4); margin-top: var(--sp-2);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md);
}
.note-text { flex: 1 1 auto; margin: 0; font-size: var(--fs-md); line-height: 1.6; min-width: 0; }
.note-item.off .note-text { color: var(--muted); text-decoration: line-through; }

/* ==========================================================================
   5. ACCOUNT SCREENS — sign-in, consent, "this link is over"
   ========================================================================== */
#login-app {
  display: flex; align-items: center; justify-content: center;
  min-height: 100vh; padding: var(--sp-6);
  background:
    radial-gradient(60% 50% at 50% 0%, rgba(91, 140, 255, .1), transparent 70%),
    var(--bg);
}
#login-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: var(--sp-8);
  max-width: 400px; width: 100%; text-align: center;
  box-shadow: var(--shadow-lg);
}
#login-card.wide { max-width: 560px; text-align: left; }
#login-card .brand-mark { width: 40px; height: 40px; font-size: 18px; border-radius: 11px; margin: 0 auto var(--sp-5); }
#login-card.wide .brand-mark { margin-left: 0; margin-right: 0; }
#login-card h1 { font-size: var(--fs-xl); margin: 0 0 var(--sp-2); }
#login-card .sub { margin: 0 auto var(--sp-5); color: var(--text-2); }
#login-card.wide .sub { margin-left: 0; }
#login-card .hint { margin-top: var(--sp-5); }
#login-card .card, #login-card .tcard { text-align: left; background: var(--surface-2); box-shadow: none; }

.google-btn {
  /* An <a>, not a <button> — the global button rules don't reach it. */
  display: flex; align-items: center; justify-content: center; gap: var(--sp-3);
  text-decoration: none; width: 100%; min-height: 42px; padding: 0 var(--sp-5);
  background: var(--accent-2); border: 1px solid var(--accent-2);
  color: #fff; border-radius: var(--r-md); font-size: var(--fs-md); font-weight: 650;
  cursor: pointer; transition: var(--speed);
}
.google-btn:hover { background: var(--accent); border-color: var(--accent); }
.google-btn.secondary { background: var(--surface-2); border-color: var(--line-strong); color: var(--text); }
.google-btn.secondary:hover { background: var(--surface-3); }
.google-btn svg { background: #fff; border-radius: 3px; padding: 2px; flex-shrink: 0; }

/* The consent screen's two lists: what an app gets, what it never gets. */
.scope-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.scope-list li {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  font-size: var(--fs-md); line-height: 1.55; color: var(--text-2);
}
.scope-list li::before { content: "✓"; color: var(--ok); font-weight: 700; flex: none; }
.scope-list.denied li::before { content: "✕"; color: var(--danger); }
.scope-title { font-size: var(--fs-sm); font-weight: 700; color: var(--text); margin: 0 0 var(--sp-2); }
.scope-title + .scope-list { margin-bottom: var(--sp-4); }

/* ==========================================================================
   6. AVATAR STUDIO (/avatar)
   ========================================================================== */
#aapp { display: grid; grid-template-columns: 320px 1fr; height: 100vh; }
@media (max-width: 900px) { #aapp { grid-template-columns: 1fr; height: auto; } }

#alist {
  background: var(--surface); border-right: 1px solid var(--line);
  padding: var(--sp-5) var(--sp-4); overflow-y: auto;
  display: flex; flex-direction: column; gap: var(--sp-3);
}
#alist header { display: flex; flex-direction: column; gap: var(--sp-1); margin-bottom: var(--sp-1); }
#alist h1 { margin: 0; font-size: var(--fs-xl); }

#avatar-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
#avatar-list li {
  display: flex; align-items: center; gap: var(--sp-3);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3); cursor: pointer; transition: border-color var(--speed);
}
#avatar-list li:hover { border-color: var(--accent-line); }
#avatar-list li.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
#avatar-list .ath {
  width: 46px; height: 48px; flex-shrink: 0; border-radius: var(--r-sm); overflow: hidden;
  border: 1px solid var(--line); display: flex; align-items: center; justify-content: center;
  font-size: 22px; background: var(--bg);
}
#avatar-list .ath img { display: block; width: 100%; height: 100%; object-fit: cover; }
#avatar-list .aname {
  flex: 1; font-size: var(--fs-md); font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#avatar-list .adel {
  flex: none; border: none; background: none; min-height: 0; cursor: pointer; font-size: 14px;
  color: var(--muted); border-radius: var(--r-sm); padding: 4px 6px; transition: var(--speed);
}
#avatar-list .adel:hover { color: var(--danger); background: var(--danger-soft); }

#abuilder {
  display: grid; grid-template-columns: 380px 1fr; gap: var(--sp-5);
  padding: var(--sp-6); overflow-y: auto; align-items: start;
}
@media (max-width: 1100px) { #abuilder { grid-template-columns: 1fr; } }

#apreview-col { position: sticky; top: 0; display: flex; flex-direction: column; gap: var(--sp-4); }
@media (max-width: 1100px) { #apreview-col { position: static; } }

#aviewer {
  position: relative; aspect-ratio: 5 / 6;
  border-radius: var(--r-xl); overflow: hidden; border: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
  background:
    radial-gradient(70% 55% at 50% 32%, rgba(91, 140, 255, 0.10), transparent 70%),
    linear-gradient(180deg, #1a212b 0%, #10141a 100%);
}
#aviewer canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
#aloader {
  position: absolute; inset: 0; z-index: 5;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--sp-4); color: var(--muted); transition: opacity .4s ease;
  background: rgba(13, 16, 20, 0.55);
}
#aloader.hidden { opacity: 0; pointer-events: none; display: flex !important; }
#aviewer-hint {
  position: absolute; bottom: 6px; left: 0; right: 0; z-index: 4;
  text-align: center; font-size: var(--fs-xs); margin: 0; pointer-events: none;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .7);
}

#asave { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--sp-4) var(--sp-5); }
#acontrols { display: flex; flex-direction: column; gap: var(--sp-4); }
#apart-cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--sp-4); align-content: start;
}
.agroup h3 { margin-bottom: var(--sp-3); }
.anote { font-size: var(--fs-sm); margin: var(--sp-3) 0 0; line-height: 1.5; }

.aswatches { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.aswatch {
  flex: none;   /* fixed circular size — don't let flex-basis override width/height */
  width: 34px; height: 34px; min-height: 0; border-radius: 50%; cursor: pointer;
  border: 2px solid var(--line); transition: transform .1s, border-color var(--speed);
  padding: 0;
}
.aswatch:hover { transform: scale(1.1); }
.aswatch.active { border-color: #fff; box-shadow: 0 0 0 2px var(--accent); }
.aorig {
  background:
    linear-gradient(135deg, transparent 44%, #ff7a7a 46%, #ff7a7a 54%, transparent 56%),
    repeating-conic-gradient(#3a424d 0% 25%, #262d36 0% 50%) 0 0 / 12px 12px;
}
.acustom {
  position: relative; display: flex; align-items: center; justify-content: center;
  background: var(--surface-2); color: var(--muted); font-size: 18px; font-weight: 700;
}
.acustom input[type="color"] {
  position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; height: 100%;
  border: 0; padding: 0;
}

/* Feature design preset chips */
.adesigns { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.adesign {
  flex: none; min-height: 30px;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--muted);
  padding: 0 var(--sp-3); border-radius: var(--r-pill); font-size: var(--fs-sm); font-weight: 600;
  cursor: pointer; transition: var(--speed); font-family: inherit;
}
.adesign:hover { border-color: var(--accent-line); color: var(--text); }
.adesign.active { background: var(--accent-2); border-color: var(--accent-2); color: #fff; }

/* ---- Print: a usage table is the one thing here anyone ever prints ------- */
@media print {
  .sidebar, .app-topbar, .page-actions, .toolbar { display: none !important; }
  .app-main { margin-left: 0; }
  html, body { background: #fff; color: #000; }
  .card, .tcard, .table-wrap, .stat-tile { border-color: #ccc; box-shadow: none; background: #fff; }
}

/* ==========================================================================
   7. REFINEMENTS
   --------------------------------------------------------------------------
   Adjustments that came out of looking at the real pages: shapes the first
   pass didn't have a name for, and two Chrome behaviours worth writing down.
   ========================================================================== */

/* An <a> wearing .btn is a button, not a link: no underline, no link blue. */
button, .btn { text-decoration: none; }
a.btn { color: var(--text); }
a.btn.primary { color: #fff; }

/* The account chip stacks its two lines. */
.user-name { display: block; }
.user-role { display: block; }

/* Inline SVG icons sit centred in their slot and never shift a baseline. */
.nav-icon { width: 18px; height: 18px; display: grid; place-items: center; flex: none; opacity: .95; }
.ic { display: block; flex: none; }
.btn .ic, button .ic, .ghost-link .ic, .page-title .ic { opacity: .9; }
.page-icon { display: inline-grid; place-items: center; color: var(--muted); }
.callout > b:first-child .ic, .card-title .ic { vertical-align: -2px; display: inline-block; }

/* A divided block WITHIN a card — a second group of fields under a rule.
   Deliberately its own class rather than a .card-foot turned sideways: a
   column flex container that is also `flex-wrap: wrap` stretches its items to
   the container's height in Chrome, which turned the backdrop swatches on the
   project page into three-hundred-pixel tiles the first time this was built. */
.card-block {
  margin-top: var(--sp-5); padding-top: var(--sp-5); border-top: 1px solid var(--line);
  display: flex; flex-direction: column; flex-wrap: nowrap; gap: var(--sp-3);
  align-items: stretch;
}
.card-block > .field { margin-bottom: 0; }

/* Vertical rhythm inside a card or a section, without a rule above it. */
.stack { display: flex; flex-direction: column; flex-wrap: nowrap; gap: var(--sp-3); align-items: stretch; }

/* The handful of "one step further down the page" modifiers. Named rather
   than inlined so the same gap is the same gap everywhere. */
.field--spaced, .form-grid--spaced, .check-row--spaced { margin-top: var(--sp-4); }
.section-head--spaced { margin-top: var(--sp-6); }
.callout--spaced { margin-top: var(--sp-4); }
.btn-row--spaced { margin-top: var(--sp-5); }
.self-start { align-self: flex-start; }
.field--minutes { max-width: 120px; }

/* A grid of fields carries no bottom margin of its own, so whatever follows
   it has to supply the gap. */
.form-grid + .field, .form-grid + .check-row, .form-grid + label.field { margin-top: var(--sp-4); }

/* A file input inside a row shares the line with the button next to it — its
   width:100% would otherwise push that button onto a line of its own. */
input[type="file"].grow { width: auto; flex: 1 1 240px; }

/* The button that leaves a detail view. Pulled out to the left so the title
   under it starts at the page's own margin, not indented by a button. */
.back-link { margin: 0 0 var(--sp-2) calc(var(--sp-3) * -1); }

/* …and when a section IS the page, as the project and connector detail
   panels are once you open one, its heading is page-sized. */
.section-head h2.detail-title { font-size: var(--fs-xl); }

/* A subhead inside a card, splitting one form into named groups. */
.limits-group {
  margin: var(--sp-5) 0 var(--sp-3);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}
.card-head + .limits-group { margin-top: 0; }

/* Save row at the end of a long form: the action and its result on one line. */
.save-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4);
  margin-top: var(--sp-5);
}
.save-bar .status { margin: 0; }

/* The studio is full-screen by nature, so it wears the brand in its own
   sidebar rather than the console shell's. */
#alist header { gap: var(--sp-3); }
.studio-brand { height: auto; padding: 0; border-bottom: 0; }
.studio-links { gap: var(--sp-4); }

/* The spinner, while a model loads in the studio. Same one the stage uses —
   copied for the same reason as the backdrops above. */
.spinner {
  width: 44px; height: 44px;
  border: 3px solid var(--line); border-top-color: var(--accent);
  border-radius: 50%; animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
