/* @foundation/ui design tokens — CSS custom-property mirror of tokens.js.
   COMBINATION B "Ivory Study" — The Study's ceremonial structure in the
   Broadsheet's warm cream + gold palette; Playfair Display type. */

:root {
  /* --- Viewport insets ----------------------------------------------------
     ONE owner for the iPhone home-indicator allowance. It used to be applied
     in two places at once (the chat wrapper AND the composer), so the phone
     double-counted it and left ~86px of dead cream under the message box.
     Anything that needs the allowance reads this, and nothing adds env() itself.

     --cc-kb is how much of the layout viewport an on-screen keyboard is
     covering, published by useKeyboardInset(). Zero on desktop and whenever the
     keyboard is down. */
  --cc-kb: 0px;
  --cc-safe-bottom: env(safe-area-inset-bottom, 0px);

  --cc-bg:         #f4f1e9;
  --cc-bg-soft:    #ece7d9;
  --cc-bg-deep:    #e3dcc9;
  --cc-bg-thread: #f1ead7;
  --cc-card:       #fbfaf4;

  --cc-navy:        #171410;
  --cc-navy-soft:   #272219;
  --cc-navy-medium: #332c20;
  --cc-navy-deep:   #0d0b07;

  /* A real navy blue for the "you" chat bubble — the --cc-navy role is a dark
     neutral in this palette (near-black), so the sender bubble needs its own
     genuinely-blue fill that carries white text on both grounds. */
  --cc-chat-mine:   #33466b;

  /* Meeting scratchpad "pens" — the two members write in one shared pad, so
     authorship has to read at a glance without a label: Alice in a dark
     neutral grey, Bob in a dark navy. Both must clear text contrast on
     the cream card, and lighten (never invert) on the dark ground. */
  --cc-pen-member-a:      #4a4a4a;
  --cc-pen-member-b:    #1e3a5f;
  --cc-pen-member-a-bg:   rgba(74, 74, 74, 0.05);
  --cc-pen-member-b-bg: rgba(30, 58, 95, 0.05);

  --cc-gold:       #b07a24;
  --cc-gold-bold:  #8f5f14;
  /* The accent as a FILL that carries WHITE content (the demo banner, the
     primary action button on Proposals/Brainstorm/Meetings/agent chat).
     --cc-gold is tuned for rules and seals and is held to no contrast target,
     so white on it measured 3.33:1 here. This is the same accent walked until
     white clears the 4.5:1 AA floor: 4.50:1 on white, 3.82:1 against the
     masthead so the button is still findable (WCAG 1.4.11). */
  --cc-gold-fill:  #a16c0c;
  --cc-gold-soft:  #a67c2e;
  --cc-gold-tint:  #f1e7d3;
  --cc-gold-pale:  #f1e7d3;
  --cc-gold-faint: rgba(176, 122, 36, 0.32);
  /* RGB triplet form of the accent, for rgba(var(--cc-gold-rgb), a) literals
     (masthead rules, borders) that need theme-aware alpha. Light = brass. */
  --cc-gold-rgb:   176, 122, 36;

  /* Interaction-layer accents (hover text, hover borders, hover tints) — kept
     as their own vars so interactions.css hovers turn orange in dark alongside
     the base accent. Light values = the original brass hover palette. */
  --cc-accent-hi:       #d8bf85;
  --cc-accent-line:     #c2a35d;
  --cc-accent-line-2:   #a98b4f;
  --cc-accent-tint-rgb: 169, 139, 79;

  --cc-ink:   #171410;
  --cc-ink-2: #57534a;
  --cc-ink-3: #8a867a;
  --cc-ink-4: #b0ab9b;

  --cc-line:   #e2dccb;
  --cc-line-2: #ece7d9;

  --cc-green: #4d7c54;
  --cc-amber: #b5791f;
  --cc-red:   #b0483e;
  --cc-green-rgb: 77, 124, 84;

  --cc-font-sans:         'Public Sans', system-ui, sans-serif;
  --cc-font-display:      'Playfair Display', Georgia, serif;
  --cc-font-display-soft: 'Playfair Display', Georgia, serif;
  --cc-font-mono:         'IBM Plex Mono', 'SF Mono', Menlo, monospace;
  /* The brand lockup (header wordmark + mobile drawer). Its own token because a
     STAMPED client's wordmark must render in THEIR display face — this was
     hardcoded as 'Cinzel' in three components, so every client's own name was
     drawn in the template's typeface. src/generated/theme.css overrides it. */
  --cc-font-wordmark:     'Cinzel', 'Trajan Pro', Georgia, serif;

  --cc-shadow-card: 0 1px 2px rgba(23, 20, 16, 0.05), 0 10px 30px rgba(23, 20, 16, 0.05);
  --cc-radius:    6px;
  --cc-radius-sm: 4px;

  /* Semantic chrome surfaces — the masthead band and the header button/pill
     "face". Broken out as their own tokens so dark mode can retune them
     without touching the components that consume them. */
  --cc-masthead: #f1ece0;
  --cc-btn-face: rgba(23, 20, 16, 0.03);

  /* Scrollbar + text selection — retuned per theme below. */
  --cc-scrollbar:       #d4cdbc;
  --cc-scrollbar-hover:  #c3bba6;
  --cc-selection: rgba(176, 122, 36, 0.20);

  /* Legacy-compat aliases — federation-remote agents (e.g. Oracle) reference
     these older var names; defined here so they resolve to Ivory values when
     an agent renders IN-SHELL (the agent's own :root only applies standalone). */
  --cc-cloud: var(--cc-bg);
  --cc-white: var(--cc-card);
  --cc-cream: var(--cc-gold-tint);
  --cc-muted: var(--cc-ink-2);
  --cc-serif: var(--cc-font-display);

  /* --- THE AGENT TOKEN BRIDGE -------------------------------------------
     Every agent built by the agent pipeline styles through `--bbl-*`. This
     Command Center defines `--cc-*`. Different namespaces — so before this
     block existed, an agent installed here rendered with EVERY `--bbl-*`
     UNDEFINED.

     That failure is worth spelling out, because it does not look like a
     failure. An undefined custom property does NOT fall back to a sensible
     value: the declaration becomes invalid at computed-value time, so
     `background: var(--bbl-card)` computes to TRANSPARENT while
     `color: var(--bbl-ink)` merely INHERITS. The result is an agent whose text
     is readable and whose cards, borders, badges and accents have all silently
     vanished — it reads as a thin or half-loaded page rather than a broken one,
     which is exactly why it survived a screenshot review. (Measured in a
     browser 2026-08-14: transparent background, inherited colour.)

     Aliases rather than copies, and that is the whole trick: a custom property
     that references another resolves AT USE, not at declaration. So these point
     at `--cc-*` and automatically follow whatever `src/generated/theme.css`
     sets for this client — including the dark-mode block, with no dark
     counterpart needed here. Verified in a browser across a theme flip.

     One block, and every agent this client ever installs inherits their brand
     with ZERO changes to the agent. Keep it exhaustive: a `--bbl-*` an agent
     can reference and this block does not name is an invisible element. */
  --bbl-bg:            var(--cc-bg);
  --bbl-bg-soft:       var(--cc-bg-soft);
  --bbl-bg-deep:       var(--cc-bg-deep);
  --bbl-card:          var(--cc-card);

  --bbl-navy:          var(--cc-navy);
  --bbl-navy-soft:     var(--cc-navy-soft);
  --bbl-navy-medium:   var(--cc-navy-medium);
  --bbl-navy-deep:     var(--cc-navy-deep);

  /* The accent family. Named "gold" in the agent kit for historical reasons —
     it is the ACCENT role, whatever colour the client actually chose. */
  --bbl-gold:          var(--cc-gold);
  --bbl-gold-bold:     var(--cc-gold-bold);
  --bbl-gold-soft:     var(--cc-gold-soft);
  --bbl-gold-tint:     var(--cc-gold-tint);
  --bbl-gold-faint:    var(--cc-gold-faint);
  --bbl-gold-rgb:      var(--cc-gold-rgb);

  --bbl-ink:           var(--cc-ink);
  --bbl-ink-2:         var(--cc-ink-2);
  --bbl-ink-3:         var(--cc-ink-3);
  --bbl-ink-4:         var(--cc-ink-4);

  --bbl-line:          var(--cc-line);
  --bbl-line-2:        var(--cc-line-2);

  --bbl-green:         var(--cc-green);
  --bbl-green-rgb:     var(--cc-green-rgb);
  --bbl-amber:         var(--cc-amber);
  --bbl-red:           var(--cc-red);

  --bbl-font-sans:     var(--cc-font-sans);
  --bbl-font-display:  var(--cc-font-display);
  --bbl-font-mono:     var(--cc-font-mono);

  --bbl-shadow-card:   var(--cc-shadow-card);

  /* Viewport insets: ONE owner (see the top of this file). An agent that reads
     these must get the host's values, never its own — double-counting the home
     indicator is what left ~86px of dead space under a composer. */
  --bbl-safe-bottom:   var(--cc-safe-bottom);
  --bbl-kb:            var(--cc-kb);

  /* The agent kit's own legacy aliases, which some older agents still use. */
  --bbl-cloud:         var(--cc-bg);
  --bbl-white:         var(--cc-card);
  --bbl-cream:         var(--cc-gold-tint);
  --bbl-muted:         var(--cc-ink-2);
  --bbl-serif:         var(--cc-font-display);

  /* Native controls (time picker, checkbox, default scrollbar) follow this. */
  color-scheme: light;
}

/* ---------------------------------------------------------------------------
   DARK MODE — "Ivory Study, after hours".
   The same warm cream + brass system relit on a warm near-black ground
   (browns, not cold grays) so the palette still reads as ivory paper turned
   down for the evening. Activated by data-theme="dark" on <html> (set pre-paint
   from localStorage in index.html; toggled at runtime by shell/theme.js).

   The saturated brass accents (--cc-gold / --cc-gold-soft) are deliberately
   NOT overridden — they read on both grounds and back the SVG icon strokes that
   consume the literal token values. Only --cc-gold-bold (text/links) brightens.
   ------------------------------------------------------------------------- */
:root[data-theme="dark"] {
  color-scheme: dark;

  --cc-bg:         #14120d;
  --cc-bg-soft:    #1b1811;
  --cc-bg-deep:    #201c14;
  --cc-bg-thread: #1d1912;
  --cc-card:       #1e1a13;

  /* "navy" is the raised-fill role (buttons, pills, icon squares, stat bands),
     always paired with light content — so in dark mode it inverts to a warm
     surface that sits ABOVE the card, not below it. Navy-as-text was migrated
     to --cc-ink so this inversion is safe. */
  --cc-navy:        #423a29;
  --cc-navy-soft:   #4d4432;
  --cc-navy-medium: #574d39;
  --cc-navy-deep:   #383021;

  /* Dark ground: lift the chat navy so it still reads blue over the warm-brown
     surface (not a muddy near-black). */
  --cc-chat-mine:   #3d5382;

  /* Scratchpad pens on the dark ground: the light-mode values are near-black
     here and would vanish, so both lift to legible tints that KEEP the
     grey-vs-navy distinction — the whole point of the two colours. */
  --cc-pen-member-a:      #b6b2aa;
  --cc-pen-member-b:    #7fa8d4;
  --cc-pen-member-a-bg:   rgba(182, 178, 170, 0.07);
  --cc-pen-member-b-bg: rgba(127, 168, 212, 0.09);

  /* Dark mode trades the ivory brass for a warm ORANGE accent — it contrasts
     harder against the warm-brown ground and reads more vividly than gold did.
     The base drives the agent-medallion rings/glyphs (via currentColor) and
     every gold fill/border; -bold is the brighter text/link/active tone. */
  --cc-gold:       #e07d33;
  --cc-gold-bold:  #f39a4d;
  /* Dark mode's white-on-gold measured WORSE than light (2.54:1), because the
     dark accent is brighter. The fill role is therefore darker than the accent
     here rather than lighter: 4.52:1 on white, 3.98:1 against the masthead. */
  --cc-gold-fill:  #bb5c00;
  --cc-gold-soft:  #cf7330;
  --cc-gold-tint:  #2c1c0f;
  --cc-gold-pale:  #2c1c0f;
  --cc-gold-faint: rgba(224, 125, 51, 0.30);
  --cc-gold-rgb:   224, 125, 51;

  --cc-accent-hi:       #f6a860;
  --cc-accent-line:     #e5893f;
  --cc-accent-line-2:   #cf7734;
  --cc-accent-tint-rgb: 224, 125, 51;

  --cc-ink:   #f2ede1;
  --cc-ink-2: #c4bca9;
  --cc-ink-3: #948c7b;
  --cc-ink-4: #6c6555;

  --cc-line:   #322c20;
  --cc-line-2: #2a251b;

  --cc-green: #6bb07a;
  --cc-amber: #d4972f;
  --cc-red:   #d9695f;
  --cc-green-rgb: 107, 176, 122;

  --cc-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.5);

  --cc-masthead: #1a1610;
  --cc-btn-face: rgba(255, 255, 255, 0.05);

  --cc-scrollbar:       #3a3428;
  --cc-scrollbar-hover:  #4a4334;
  --cc-selection: rgba(215, 165, 63, 0.28);
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  background: var(--cc-bg);
  color: var(--cc-ink);
  font-family: var(--cc-font-sans);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

::selection { background: var(--cc-selection); }
* { scrollbar-color: var(--cc-scrollbar) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--cc-scrollbar); border-radius: 999px; border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--cc-scrollbar-hover); border: 3px solid transparent; background-clip: content-box; }

/* Keyboard up: the keyboard COVERS the home indicator, so the safe-area
   allowance is no longer protecting anything — it just becomes dead space
   between the message box and the top of the keys. Zero it while the keyboard
   is open; useKeyboardInset() puts this class on <html>. */
:root.cc-kb-open {
  --cc-safe-bottom: 0px;
}

/* Keyboard up ALSO retires the phone tab bar. The layout viewport is already
   collapsed to a strip above the keys; a row of navigation between the field
   you are typing in and the keyboard is the most expensive 56px on the screen,
   and nobody changes tab mid-sentence. It comes back when the keyboard drops. */
:root.cc-kb-open [data-testid="mobile-tab-bar"] {
  display: none;
}

/* ---------------------------------------------------------------------------
   iOS FOCUS ZOOM — the one-rule fix.

   Mobile Safari ZOOMS THE WHOLE PAGE IN when you focus a form control whose
   font-size is under 16px, and it does not zoom back out when you leave the
   field. Every text input in this product was 13.5px (the shared INPUT_STYLE)
   or smaller, so tapping any of them — the client search, the dossier
   assistant, every field of every dialog — lurched the layout sideways and left
   it there. Measured on a stamped client 2026-08-25 across every form surface.

   The usual "fix" is `maximum-scale=1, user-scalable=no` on the viewport meta.
   That is not a fix, it is a WCAG 1.4.4 failure: it disables pinch-zoom for
   everyone, permanently, to paper over a font size. index.html deliberately
   does NOT do that, which is why this rule has to.

   `!important` because every control in this codebase is styled with an INLINE
   px font-size, and an inline declaration outranks any stylesheet rule without
   it. Scoped to `pointer: coarse` so the desktop's denser 13.5px controls are
   untouched — this is a touch-device correction, not a redesign.

   16px is the floor, not a target: `max(16px, …)` would be the same thing with
   more moving parts, since nothing in here is above 16 to begin with. */
/* Gated on `pointer: coarse` ALONE, unlike the touch-target rules, and that
   asymmetry is deliberate. The zoom bug exists only on a touch device, so a
   desktop browser resized to phone width has nothing to fix — and raising its
   inputs to 16px there WOULD be a visible regression in the one place the
   layout is reviewed. A control that is merely narrow is not a control being
   touched. */
@media (pointer: coarse) {
  input,
  textarea,
  select {
    font-size: 16px !important;
  }
}

/* ---------------------------------------------------------------------------
   THE TOUCH-TARGET FLOOR, app-wide.

   Measured across every phone surface of a stamped client 2026-08-25: the
   dashboard's month arrows 28x28, its panel buttons 30, the support footer's
   button 31, page actions 36, the masthead hamburger 40. The craft bar is 44
   (Apple 44pt / Material 48dp), the research minimum for a one-handed thumb is
   ~35px, and WCAG 2.5.8's hard floor is 24 -- so the smallest of these was
   failing the floor, not just the bar.

   Fixing forty inline style objects one at a time is how half of them get
   missed and how the next component added to the product starts under the bar
   again. One rule, at the root, is the invariant.

   `(pointer: coarse), (max-width: 700px)` is a union for the reason the bespoke
   sheet's twin is: coarse is the honest signal on the device and is FALSE in a
   desktop browser at 390px, which is where this layout is actually reviewed.

   THE EXCLUSIONS ARE THE LOAD-BEARING PART. Everything here is a control whose
   height is DERIVED from something other than ergonomics, and forcing 44px on
   it corrupts the thing it is derived from:
     .cc-cal-event  - absolutely positioned, sized in minutes. A 30-minute
                      meeting stretched to 44px detaches from its hour grid.
     .cc-cal-slot   - the hour cells behind it, already 46px, same geometry.
     .cc-skip-link  - visually hidden until focused; sizing it reveals it.
     [role="tab"] inside a scrolling tab row and the month grid's day cells are
     left alone for the same reason -- they are already >=44 by construction.
   A control that is inline BY NATURE (a mailto: inside a sentence) is also out:
   `display` is untouched here, so an inline element ignores min-height and is
   unaffected rather than broken. Those are sized where they are written.
   --------------------------------------------------------------------------- */
/* Desktop placement for the dashboard calendar's control group. It lives in the
   stylesheet rather than inline so the phone rule further down can recentre it
   by ordinary cascade — an inline `justify-self` would have forced an
   !important. It must stay ABOVE that media block: the two selectors have equal
   specificity, so document order is the only thing deciding the winner. */
.cc-cal-head > .cc-cal-nav {
  justify-self: end;
}

@media (pointer: coarse), (max-width: 700px) {
  button:not(.cc-cal-event):not(.cc-cal-slot):not(.cc-skip-link),
  [role="button"]:not(.cc-cal-event):not(.cc-cal-slot),
  input:not([type="checkbox"]):not([type="radio"]),
  select {
    min-height: 44px;
  }

  /* The craft bar is about the SMALLER axis, so a 40px-wide button fails it
     however tall it is -- which is exactly how the Rolodex "Edit" survived a
     min-height-only pass at 40px while "Delete" beside it passed at 55. */
  button:not(.cc-cal-event):not(.cc-cal-slot):not(.cc-skip-link) {
    min-width: 44px;
  }
}

@media (max-width: 700px) {
  /* THE DASHBOARD CALENDAR HEAD, restacked. This is the direct COST of the touch
     floor immediately above, and it belongs beside it.

     CalendarPanel's head is one row: [spacer] [month title] [Today | < | > |
     New event]. Growing those four controls from 28px to the 44px floor took the
     control group from 236px to 268px, and the row's minimum from something that
     fitted a phone to something that does not. MEASURED 2026-08-27 on emulated
     iPhone 13 / iPhone SE / Pixel 7, in the fullest configuration this head row
     ever renders — a client with a bespoke calendar page (so "New event" is
     present) viewing a month other than the current one (so "Today" is present
     too). That combination is live on a real client today, which is why it is
     the one that was measured rather than the bare four-control default:

       before: "SEPTEMBER 2026" took TWO line boxes, head row 54px not 27px,
               and the document scrolled sideways at 445px against a 390px phone.

     Two lines of defect from one cause, and the wrap was only the visible half.
     Restacking to title-over-controls fixes both: the title gets the full width
     (so it never wraps) and the control group gets its own row (so nothing
     overflows).

     WIDTH ONLY, not the touch floor's `(pointer: coarse), (max-width: 700px)`
     union, and the asymmetry is the point. What breaks the row is that it is too
     NARROW to hold 268px of controls beside a 195px title; a wide touch device
     has room for both. Gating on the union would have restacked an iPad at
     820px, where one row fits with ~330px to spare. 700px is also exactly the
     breakpoint HomePage's own useViewportNarrow(700) uses to switch to
     MobileHome, so the head restacks precisely when the app is in its phone
     layout — one number, not two that can drift apart.
     Swept 2026-08-27 at 320/375/390/412/430/600/700/701/768/900/1024/1280/1440:
     one line box and zero horizontal overflow at every width, stacked at <=700
     and one row at >=701.

     `!important` for the same reason the iOS focus-zoom rule above needs it, and
     it is the only pair here that does: the head row's track definition is
     written as an INLINE style object in CalendarPanel.jsx (HEAD_STYLE), and an
     inline declaration outranks any stylesheet rule without it. The CHILDREN do
     not need it — they are placed with `grid-area`, which reads correctly
     against either template, which is exactly why they were written that way. */
  .cc-cal-head {
    grid-template-areas: "title" "nav" !important;
    grid-template-columns: minmax(0, 1fr) !important;
  }

  /* The spacer only exists to balance the control group across a three-track
     row. With one track there is nothing to balance, and leaving it in place
     would draw an empty third row. */
  .cc-cal-head > .cc-cal-pad {
    display: none;
  }

  .cc-cal-head > .cc-cal-nav {
    justify-self: center;
    flex-wrap: wrap;
    justify-content: center;
  }
}

/* ---------------------------------------------------------------------------
   NO BROWSER BACK-SWIPE (2026-08-26). A left-to-right swipe on a phone is the
   shell's own gesture — it opens the nav drawer (Header.jsx) — and the
   browser's history-back swipe was winning the race: "swiping left to right
   is taking me back to last page. it should always open up the sidebar."
   `overscroll-behavior-x: none` is the standard switch that disables the
   navigation gesture in Chrome, Edge and Android WebView while leaving
   vertical scrolling untouched. iOS Safari does not offer web content this
   control for its edge swipe; there the edge stays the OS's and everything
   inboard of it is ours, which the drawer handler already handles.
   --------------------------------------------------------------------------- */
html, body {
  overscroll-behavior-x: none;
}
/* GENERATED FILE (scaffold-owned) — src/generated/theme.css
 *
 * Lauren Bowen's palette, generated from
 * clients/lauren-bowen/client.config.json by scripts/lib/palette.mjs.
 *
 * Source brand colors:
 *   primary #828093   accent #0d49d3
 *   neutral #f1f1f7 (synthesised from the primary — none given at intake)
 *   background derived from the neutral (no explicit ground chosen at intake)
 *
 * Ramps are built in OKLCH (perceptually uniform), so lightness moves without
 * the hue drift plain hex arithmetic produces. Every foreground role is then
 * walked until it clears its WCAG target against the ground it actually sits
 * on — a brand color chosen for a logo is not automatically a legible UI color.
 *
 * Measured contrast, light: ink 12.58:1 on bg-deep, ink-2 5.63:1 on bg-deep, ink-3 3.01:1 on bg-deep, gold-bold 5.23:1 on bg-deep, green 3.65:1 on bg-deep, amber 3.91:1 on bg-deep, red 4.13:1 on bg-deep, white on navy 14.61:1, white on chat-mine 9.39:1, white on gold-fill 7.21:1
 * Measured contrast, dark:  ink 14.05:1 on bg-deep, ink-2 8.68:1 on bg-deep, ink-3 4.62:1 on bg-deep, gold-bold 5.49:1 on bg-deep, green 6.77:1 on bg-deep, amber 6.45:1 on bg-deep, red 6.16:1 on bg-deep, white on navy 9.32:1, white on chat-mine 7.28:1, white on gold-fill 4.61:1
 *
 * Loaded AFTER tokens.css and overrides it. HAND-EDITS ARE WRONG: rebrand by
 * editing the client config and re-running the scaffolder, so the config and
 * the UI can never disagree.
 */

:root {
  --cc-bg: #f2f2f8;
  --cc-bg-soft: #e7e6ec;
  --cc-bg-deep: #dbdbe1;
  --cc-bg-thread: #ebeaf0;
  --cc-card: #faf9ff;
  --cc-masthead: #ececf2;
  --cc-navy: #292736;
  --cc-navy-soft: #3b394a;
  --cc-navy-medium: #4e4c5d;
  --cc-navy-deep: #1c1928;
  --cc-chat-mine: #47416b;
  --cc-pen-member-a: #4d4c52;
  --cc-pen-member-b: #474266;
  --cc-pen-member-a-bg: rgba(77, 76, 82, 0.05);
  --cc-pen-member-b-bg: rgba(71, 66, 102, 0.05);
  --cc-gold: #0d49d3;
  --cc-gold-bold: #0d49d3;
  --cc-gold-fill: #0d49d3;
  --cc-gold-soft: #0037c2;
  --cc-gold-tint: #d7e5ff;
  --cc-gold-pale: #d7e5ff;
  --cc-gold-faint: rgba(13, 73, 211, 0.32);
  --cc-gold-rgb: 13, 73, 211;
  --cc-accent-hi: #3e7eff;
  --cc-accent-line: #2360eb;
  --cc-accent-line-2: #033fc9;
  --cc-accent-tint-rgb: 3, 63, 201;
  --cc-ink: #1a1a1e;
  --cc-ink-2: #525257;
  --cc-ink-3: #7c7c81;
  --cc-ink-4: #a4a4a9;
  --cc-line: #d1d0d8;
  --cc-line-2: #e3e2e9;
  --cc-green: #447b46;
  --cc-amber: #965e00;
  --cc-red: #b24039;
  --cc-green-rgb: 68, 123, 70;
  --cc-shadow-card: 0 1px 2px rgba(26, 26, 30, 0.05), 0 10px 30px rgba(26, 26, 30, 0.05);
  --cc-btn-face: rgba(26, 26, 30, 0.03);
  --cc-scrollbar: #bdbcc6;
  --cc-scrollbar-hover: #a4a3ac;
  --cc-selection: rgba(13, 73, 211, 0.2);
  --cc-font-sans: 'Fraunces', system-ui, -apple-system, sans-serif;
  --cc-font-display: 'Fraunces', Georgia, serif;
  --cc-font-display-soft: 'Fraunces', Georgia, serif;
  --cc-font-wordmark: 'Fraunces', Georgia, serif;
  --cc-font-mono: 'IBM Plex Mono', 'SF Mono', Menlo, monospace;
  --cc-brand-primary: #828093;
  --cc-brand-accent: #0d49d3;
  --cc-brand-background: #f2f2f8;
}

:root[data-theme="dark"] {
  --cc-bg: #101014;
  --cc-bg-soft: #19191d;
  --cc-bg-deep: #202024;
  --cc-bg-thread: #1c1c20;
  --cc-card: #1d1d21;
  --cc-masthead: #151519;
  --cc-navy: #474556;
  --cc-navy-soft: #565466;
  --cc-navy-medium: #646274;
  --cc-navy-deep: #3b394a;
  --cc-chat-mine: #58517c;
  --cc-pen-member-a: #aaaab1;
  --cc-pen-member-b: #a49fc8;
  --cc-pen-member-a-bg: rgba(170, 170, 177, 0.07);
  --cc-pen-member-b-bg: rgba(164, 159, 200, 0.09);
  --cc-gold: #5295ff;
  --cc-gold-bold: #5295ff;
  --cc-gold-fill: #2d6bf7;
  --cc-gold-soft: #4384ff;
  --cc-gold-tint: #141f35;
  --cc-gold-pale: #141f35;
  --cc-gold-faint: rgba(82, 149, 255, 0.3);
  --cc-gold-rgb: 82, 149, 255;
  --cc-accent-hi: #6db3ff;
  --cc-accent-line: #589bff;
  --cc-accent-line-2: #498bff;
  --cc-accent-tint-rgb: 73, 139, 255;
  --cc-ink: #eeeef4;
  --cc-ink-2: #bdbdc3;
  --cc-ink-3: #89888e;
  --cc-ink-4: #636268;
  --cc-line: #2e2d33;
  --cc-line-2: #242328;
  --cc-green: #7cb57d;
  --cc-amber: #d49838;
  --cc-red: #f47c70;
  --cc-green-rgb: 124, 181, 125;
  --cc-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.5);
  --cc-btn-face: rgba(255, 255, 255, 0.05);
  --cc-scrollbar: #38373e;
  --cc-scrollbar-hover: #4d4c54;
  --cc-selection: rgba(82, 149, 255, 0.28);
}
/* Atelier profile — token overrides, CLIENT edition.
 *
 * The port of BBL's own atelier/tokens-atelier.css onto a client Command
 * Center. Everything here is scoped under :root[data-ui="atelier"], stamped
 * pre-paint by index.html, so with the stamp removed this file is completely
 * inert and the classic UI is byte-identical.
 *
 * ── THE ONE RULE THAT MAKES THIS DIFFERENT FROM BBL'S ─────────────────────
 *
 * BBL's Atelier profile hardcodes BBL's palette: pure white, #15160f ink,
 * #b08a3c gold, Bodoni. A client Command Center may not do that. The client's
 * palette is GENERATED from their own brand colours by scripts/lib/palette.mjs
 * (src/generated/theme.css), walked to WCAG targets, and it is the entire
 * reason a client CC looks like the client rather than like us. Overwriting it
 * here would ship the operator's own gold to every client we have.
 *
 * So this file overrides COMPOSITION ROLES ONLY:
 *
 *   grounds       page/card/masthead become one sheet of paper
 *   hairlines     a second, stronger rule weight for control borders
 *   elevation     cards go FLAT; only floating layers keep a shadow
 *   radii         8px panels / 6px controls (the locked "Bento" density)
 *   button face   the card ground rather than a tinted wash
 *
 * and touches NO hue role. --cc-navy*, --cc-gold*, --cc-accent*, the status
 * hues, --cc-chat-mine, the member pens and every font var are left exactly as
 * the client's generated theme set them. A client whose brand is indigo and
 * green stays indigo-and-green in the Atelier; it just wears the Atelier's
 * composition.
 *
 * The wash grounds are mixed from --cc-line — itself derived from the client's
 * `neutral` brand colour — rather than from a literal grey, so a client who
 * chose a warm neutral gets a warm wash and a cool one gets a cool wash. Each
 * color-mix() is preceded by a plain fallback for any engine that cannot parse
 * it: the fallback is a correct, slightly flatter answer, never a broken one.
 *
 * ── LOAD ORDER IS LOAD-BEARING ────────────────────────────────────────────
 *
 * index.html links this AFTER src/generated/theme.css. :root[data-ui="atelier"]
 * ties :root on specificity, so document order is what makes these values win.
 * The member's own brand-colour override (the inline <style> injected later in
 * index.html) still wins over both — it sets hues, which this file does not
 * touch, so the two never collide.
 *
 * ── DARK MODE SURVIVES ────────────────────────────────────────────────────
 *
 * BBL's Atelier is deliberately light-only: its profile block overrides the
 * same properties the dark block sets, so with Atelier on the dark toggle does
 * nothing. That is not acceptable here — a client CC ships a working Appearance
 * setting and taking it away in a re-skin is a regression, not a redesign. So
 * every override below is written twice, once per theme, and the dark half is
 * scoped :root[data-ui="atelier"][data-theme="dark"] so it outranks the light
 * half on specificity regardless of order.
 */

:root[data-ui="atelier"] {
  /* ── Grounds: the page IS the paper ──────────────────────────────────────
     The classic client CC separates page from card (#f7f7f8 under #ffffff) and
     gives the masthead a third tint again, so a panel reads as a tile ON a
     surface and the masthead as a band ACROSS it. The Atelier composition
     removes both separations: page, card and masthead are one sheet and the
     hairlines do all the dividing.

     ── WHY THESE POINT AT --cc-bg AND NEVER AT A LITERAL WHITE ─────────────

     Because --cc-bg is the CLIENT'S ground and this file must not have an
     opinion about it. Two reasons, and the second one is a bug I shipped and
     had to come back for:

     1. A client whose brand background is a warm cream keeps their cream. The
        composition is "card and page are the same sheet", not "the sheet is
        white" — and pinning it white would quietly delete a brand decision the
        palette engine had already made.
     2. It is the ONLY way dark mode survives. :root[data-ui="atelier"] and
        theme.css's :root[data-theme="dark"] have IDENTICAL specificity, and
        this file loads second — so a literal --cc-bg here beats the dark
        ground and paints a dark-mode session's light-ink text onto a white
        page. Which is exactly what it did: unreadable, and it looked fine in
        every light-mode screenshot. Never assigning --cc-bg means there is
        nothing to lose that fight with.

     The washes mix from the client's own hairline toward their own ground, so
     they work in BOTH directions without being written twice: --cc-line is
     darker than the ground in light and lighter than it in dark, so the same
     expression darkens a light wash and lifts a dark one. */
  --cc-card:      var(--cc-bg);
  --cc-masthead:  var(--cc-bg);

  --cc-bg-soft:   color-mix(in srgb, var(--cc-line) 26%, var(--cc-bg));
  --cc-bg-deep:   color-mix(in srgb, var(--cc-line) 44%, var(--cc-bg));
  --cc-bg-thread: color-mix(in srgb, var(--cc-line) 14%, var(--cc-bg));

  /* ── Hairlines: a second weight ─────────────────────────────────────────
     --cc-line stays the client's own default rule. --cc-line-strong is NEW and
     Atelier-only: the mockup's control-border weight, used by pills, icon
     buttons, table heads and the sheet grab-handle. Mixed toward ink from the
     client's own line so it is the same hue, one step firmer. */
  --cc-line-strong: #d5d5d2;
  --cc-line-strong: color-mix(in srgb, var(--cc-line) 78%, var(--cc-ink));

  /* ── Elevation: FLAT ─────────────────────────────────────────────────────
     Variation 3 "Bento" (locked 2026-09-04): panels and cards carry no shadow
     at all — the hairline is the edge. Floating layers (dropdowns, the search
     overlay, popovers) are the exception and take --at-shadow-pop, because a
     layer that genuinely sits above the page has to say so. */
  --cc-shadow-card: none;
  --at-shadow-pop:
    0 1px 2px rgba(0, 0, 0, 0.04),
    0 18px 44px rgba(0, 0, 0, 0.07);

  /* ── Radii: the Bento density ───────────────────────────────────────────
     8px panels, 6px controls. tokens.js resolves bblRadius.md/.sm through
     these custom properties, so every inline-styled component moves with them
     — which is the whole reason that indirection exists. */
  --cc-radius:    8px;
  --cc-radius-sm: 6px;

  /* Button faces sit ON the paper rather than being a tinted panel of their
     own; the hairline is what makes them a button. */
  --cc-btn-face: var(--cc-bg);
}

/* ── The corrections dark actually needs ────────────────────────────────────
   Almost nothing, because the block above is written in terms of the client's
   own ground and hairline and therefore already follows the theme. Only two
   things genuinely differ after dark, and both are about a hairline having
   less to work with on a near-black ground:

     · a card given EXACTLY the page ground disappears — in light the hairline
       carries the edge on its own, in dark it needs the panel lifted a step
       off the page as well;
     · --cc-line-strong takes a longer walk toward the ink. The light
       expression is already correct in both themes (--cc-ink inverts with the
       theme, so mixing toward it darkens a light rule and lightens a dark
       one); it simply needs MORE of that walk here, because a near-black
       ground gives a hairline less to separate itself from.

   Higher specificity than the block above (three compound parts against two),
   so this wins regardless of source order. */
:root[data-ui="atelier"][data-theme="dark"] {
  --cc-card: color-mix(in srgb, var(--cc-line) 34%, var(--cc-bg));

  --cc-line-strong: #46473b;
  --cc-line-strong: color-mix(in srgb, var(--cc-line) 62%, var(--cc-ink));

  --at-shadow-pop:
    0 1px 2px rgba(0, 0, 0, 0.4),
    0 20px 48px rgba(0, 0, 0, 0.55);
}

/* index.html's pre-mount loader stamps a font shorthand literal (it renders
   before any bundle, so it cannot read tokens.js). Point it at the client's own
   display face so the very first frame is already in their typography. */
:root[data-ui="atelier"] #root:empty::before {
  font-family: var(--cc-font-display, 'Playfair Display', Georgia, serif);
}
/* Atelier profile — component styles, CLIENT edition.
 *
 * Ported from BBL's own atelier/atelier.css (the approved cc-full-template
 * mockup, locked 2026-09-04). Two systematic changes were made in the port and
 * nothing else was invented:
 *
 *   1. --bbl-* became --cc-*, the client template's token namespace.
 *   2. Every literal BBL hue was replaced by the token that carries it, so a
 *      focus ring, a hover glow and an underline are the CLIENT's accent
 *      rather than the operator's gold. rgba() literals became
 *      color-mix(in srgb, var(--cc-gold) N%, transparent) for the same reason.
 *
 * BBL-only sections were dropped rather than ported dead: the forest agency
 * roster band, the engraved agent marks, the Records dev-log accordion, the
 * Time .barrow bars, the Tasks toolbar and the Consults lobby rows have no
 * counterpart in a client Command Center.
 *
 * EVERYTHING here is scoped under [data-ui="atelier"]; keyframe names are
 * at-prefixed (keyframes cannot be attribute-scoped, so the prefix is the
 * collision guard). With the stamp removed, no element carries these classes
 * and no rule can match — the classic UI is untouched.
 */

/* ================= THE ARRIVAL — "The Composition" =================
   Mark rises, rule draws, page lifts in. Timings locked in the mockup:
   veil-out at 1.6s, mark-in .9s@.05s, word .7s@.5s, rule .8s@.35s. */
:root[data-ui="atelier"] .at-veil {
  position: fixed; inset: 0; z-index: 80; display: grid; place-items: center;
  background: transparent; pointer-events: none;
}
:root[data-ui="atelier"] .at-veil-bg { position: absolute; inset: 0; background: var(--cc-bg); }
:root[data-ui="atelier"] .at-veil-stage { position: relative; display: grid; place-items: center; gap: 16px; }
:root[data-ui="atelier"] .at-veil img { display: block; width: 74px; height: auto; opacity: 0; }
/* THE MARK IS A BLACK PNG. On the light ground that is the whole design; after
   dark it is a black silhouette on a near-black veil — an arrival that renders
   a gold rule, a wordmark, and a hole where the mark should be.
   BBL's own Atelier never hit this because that profile is light-only; a
   client Command Center ships a working dark mode and so must this.
   Same mechanism the phone bar uses for the same artwork (.cc-mobile-mark in
   home/interactions.css): flatten to black, then invert to a white silhouette.
   Safe here in a way it is NOT on a client's own logo — this file is the
   operator's mark, one known asset, monochrome by construction.
   Scoped to .at-veil-mark, NOT to `.at-veil img`. Under a white-label stamp
   the fallback in this slot is the CLIENT's artwork, and inverting a logo we
   do not own is precisely the destruction BrandMark.jsx refuses to do — see
   its plate note. The class is only ever put on the operator's own file. */
:root[data-ui="atelier"][data-theme="dark"] .at-veil-mark {
  filter: brightness(0) invert(1);
}

/* ── THE ARRIVAL WEARS THE OPERATOR'S TYPOGRAPHY, NOT THE CLIENT'S ────────
   Cinzel and the gold are LITERALS here, and that is the point rather than an
   oversight. Every other rule in this file resolves through the client's
   palette and type tokens, because every other surface is the client's. The
   arrival is not: it is the same composition on every Command Center, so it
   must not move when a client picks a different display face or a different
   accent. Reading --cc-font-wordmark and --cc-gold here is exactly what made
   this one render in Playfair over a green rule.

   Cinzel is loaded by index.html OUTSIDE the CC:FONTS markers, so a re-stamp
   that rewrites the client's own faces cannot take it away. */
:root[data-ui="atelier"] .at-veil-word {
  font-family: 'Cinzel', Constantia, Georgia, serif; font-size: 13px;
  letter-spacing: .5em; text-transform: uppercase;
  /* The ink token, not a literal — this is the one value that SHOULD follow
     the theme, because the veil covers the page with the page's own ground and
     a fixed near-black would be invisible on it after dark. */
  color: var(--cc-ink);
  opacity: 0; padding-left: .5em; text-align: center;
}
:root[data-ui="atelier"] .at-veil-rule {
  width: 0; height: 1px;
  /* The operator's gold. */
  background: #b08a3c;
  /* The drawn rule's final length — the keyframe reads this, so the phone
     block below can shorten the rule without a second keyframe. */
  --at-rule-w: 150px;
}
:root[data-ui="atelier"] .at-run .at-veil-bg { animation: at-veil-out .6s ease 1.6s forwards; }
:root[data-ui="atelier"] .at-run .at-veil-stage { animation: at-veil-out .5s ease 1.6s forwards; }
:root[data-ui="atelier"] .at-run img { animation: at-mark-in .9s cubic-bezier(.2,.7,.2,1) .05s forwards; }
:root[data-ui="atelier"] .at-run .at-veil-word { animation: at-mark-in .7s ease .5s forwards; }
:root[data-ui="atelier"] .at-run .at-veil-rule { animation: at-rule-out .8s cubic-bezier(.4,0,.2,1) .35s forwards; }
@keyframes at-mark-in { from { opacity: 0; transform: translateY(8px) scale(.94); } to { opacity: 1; transform: none; } }
@keyframes at-rule-out { to { width: var(--at-rule-w, 150px); } }
@keyframes at-veil-out { to { opacity: 0; visibility: hidden; } }
@keyframes at-mark-in-m { from { opacity: 0; transform: translateY(14px) scale(.9); } to { opacity: 1; transform: none; } }

/* The arrival on PHONES: retuned rather than scaled down. The stage is lifted
   above true centre, which also masks the downward shift when browser chrome
   collapses mid-animation (a fixed inset:0 layer grows at the BOTTOM edge when
   the address bar hides). Every beat the chime keys on is untouched. */
@media (max-width: 700px) {
  :root[data-ui="atelier"] .at-veil {
    padding-bottom: calc(8vh + env(safe-area-inset-bottom));
    box-sizing: border-box;
  }
  :root[data-ui="atelier"] .at-veil-stage { gap: 14px; }
  :root[data-ui="atelier"] .at-veil img { width: clamp(56px, 17vw, 70px); }
  :root[data-ui="atelier"] .at-veil-word {
    font-size: clamp(10.5px, 3.1vw, 12px);
    letter-spacing: .42em;
    padding-left: .42em;
  }
  :root[data-ui="atelier"] .at-veil-rule { --at-rule-w: clamp(96px, 34vw, 140px); }
  :root[data-ui="atelier"] .at-run img { animation-name: at-mark-in-m; animation-duration: .8s; }
  :root[data-ui="atelier"] .at-run .at-veil-word { animation-duration: .6s; }
  :root[data-ui="atelier"] .at-run .at-veil-rule { animation-duration: .7s; }
}

/* ================= MASTHEAD ================= */
/* Fluid frame — fills the viewport with a readable ceiling; no dead margins.
   NOTE the borderTop: the client template puts a 3px rule of the client's
   PRIMARY colour across the top of every masthead, because primary is
   otherwise nearly invisible on a Command Center (2026-08-24). That rule is
   data about whose Command Center this is, not decoration, so the Atelier
   masthead keeps it. */
:root[data-ui="atelier"] .at-headwrap {
  position: relative;
  background: var(--cc-bg);
  border-top: 3px solid var(--cc-navy);
  border-bottom: 1px solid var(--cc-line);
  flex-shrink: 0;
  /* Its own stacking context ABOVE the page content, so the nav dropdowns
     always paint in front of what follows. */
  z-index: 50;
}
:root[data-ui="atelier"] .at-frame {
  max-width: 1720px; margin: 0 auto; padding: 0 clamp(16px, 3vw, 48px);
}
:root[data-ui="atelier"] .at-header {
  display: flex; align-items: center; gap: 26px; padding: 18px 0 16px;
}

/* Compact single-row lockup: mark + wordmark. The mark is BrandMark, which may
   be a logo, initials set as type, or nothing at all — a client with
   monogram.hidden gets a pure-type lockup, which is the right answer when the
   name IS the identity. */
:root[data-ui="atelier"] .at-lockup {
  display: flex; align-items: flex-end; gap: 13px; flex-shrink: 0;
  text-decoration: none; color: inherit;
  background: transparent; border: none; padding: 0; cursor: pointer;
  font: inherit; text-align: left;
}
:root[data-ui="atelier"] .at-lockup img { display: block; width: auto; }
:root[data-ui="atelier"] .at-wordmark {
  font-family: var(--cc-font-wordmark, var(--cc-font-display)); font-weight: 600;
  font-size: 16px; letter-spacing: .18em; text-transform: uppercase;
  line-height: 1; padding-bottom: 2px; color: var(--cc-ink);
  white-space: nowrap;
}
:root[data-ui="atelier"] .at-wordmark small {
  display: block; font-family: var(--cc-font-sans); font-weight: 600;
  font-size: 8.5px; letter-spacing: .34em; color: var(--cc-ink-3); margin-top: 5px;
}

/* Small-caps horizontal nav with the full-label accent underline. */
:root[data-ui="atelier"] .at-nav { display: flex; gap: 2px; margin-left: 4px; }
:root[data-ui="atelier"] .at-nav a {
  position: relative; color: var(--cc-ink-2); text-decoration: none;
  font-size: 12.5px; letter-spacing: .09em; text-transform: uppercase;
  padding: 10px 13px; transition: color .15s; cursor: pointer;
}
/* The active underline runs edge-to-edge of the tab label (a touch beyond),
   never narrower than the word. */
:root[data-ui="atelier"] .at-nav a::after {
  content: ''; position: absolute; left: 9px; right: 9px; bottom: 4px;
  height: 2px; background: var(--cc-gold); border-radius: 2px;
  transform: scaleX(0); transform-origin: left;
  transition: transform .22s cubic-bezier(.2,.7,.2,1);
}
:root[data-ui="atelier"] .at-nav a:hover { color: var(--cc-ink); }
:root[data-ui="atelier"] .at-nav a:hover::after { transform: scaleX(1); }
:root[data-ui="atelier"] .at-nav a[aria-current] { color: var(--cc-ink); }
:root[data-ui="atelier"] .at-nav a[aria-current]::after { transform: scaleX(1); }

/* THE SUB-TAB ROW (template 1.24.0) — the active page's own children, one tier
   down. It exists here because the Atelier masthead REPLACES the classic one
   outright: without this, a client who declares `children` on a page would get
   a schema-supported feature that renders nowhere, and nothing would say so.

   It is quieter than .at-nav by SIZE and TRACKING, never by contrast. The
   classic Header.jsx SUBNAV comment records why: ink-3 measures 3.40:1 on the
   masthead, under the 4.5:1 AA floor at small sizes, so the second tier holds
   ink-2/ink exactly as the first does and the hierarchy is carried by the type
   scale and by a THINNER rule — a rule is not text and carries no contrast
   floor, which is the same reasoning that moved the accent onto one in
   1.17.0-rc.1. */
:root[data-ui="atelier"] .at-subnav {
  display: flex; flex-wrap: wrap; align-items: center; gap: 2px;
  padding: 0 0 10px; margin-left: 4px;
}
:root[data-ui="atelier"] .at-subnav a {
  position: relative; color: var(--cc-ink-2); text-decoration: none;
  /* The 24px WCAG 2.5.8 target floor the nav row was fixed to in 1.17.0-rc.1.
     A second row of links is not a second-class row of links. */
  display: inline-flex; align-items: center; min-height: 24px;
  font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase;
  padding: 4px 10px; transition: color .15s; cursor: pointer;
}
:root[data-ui="atelier"] .at-subnav a::after {
  content: ''; position: absolute; left: 7px; right: 7px; bottom: 0;
  height: 1px; background: var(--cc-gold); border-radius: 1px;
  transform: scaleX(0); transform-origin: left;
  transition: transform .22s cubic-bezier(.2,.7,.2,1);
}
:root[data-ui="atelier"] .at-subnav a:hover { color: var(--cc-ink); }
:root[data-ui="atelier"] .at-subnav a:hover::after { transform: scaleX(1); }
:root[data-ui="atelier"] .at-subnav a[aria-current] { color: var(--cc-ink); }
:root[data-ui="atelier"] .at-subnav a[aria-current]::after { transform: scaleX(1); }

/* Hover dropdowns — a tab reveals its sub-pages for direct navigation. */
:root[data-ui="atelier"] .at-navitem { position: relative; }
/* Permanent invisible hover extension: during the .15s open delay the pointer
   often drifts DOWN into the 10px gap before the panel exists, killing :hover
   — this strip keeps .at-navitem:hover alive across the gap. */
:root[data-ui="atelier"] .at-navitem::after {
  content: ''; position: absolute; top: 100%; left: 0; right: 0; height: 14px;
}
:root[data-ui="atelier"] .at-drop {
  position: absolute; top: calc(100% + 10px); left: 6px; min-width: 176px;
  background: var(--cc-bg); border: 1px solid var(--cc-line);
  border-radius: 12px; box-shadow: var(--at-shadow-pop); padding: 7px; z-index: 60;
  opacity: 0; visibility: hidden; transform: translateY(7px);
  transition: opacity .18s ease, transform .18s cubic-bezier(.2,.7,.2,1), visibility .18s;
}
/* Invisible bridge so the pointer can cross the gap without closing it. */
:root[data-ui="atelier"] .at-drop::before {
  content: ''; position: absolute; top: -12px; left: 0; right: 0; height: 12px;
}
/* Keyboard focus (focus-visible) opens a dropdown; a mouse CLICK must not pin
   one open — that's how two could show at once. */
:root[data-ui="atelier"] .at-navitem:hover .at-drop,
:root[data-ui="atelier"] .at-navitem:has(:focus-visible) .at-drop {
  opacity: 1; visibility: visible; transform: none; transition-delay: .15s;
}
:root[data-ui="atelier"] .at-drop a {
  display: block; padding: 9px 13px; font-size: 12.5px; letter-spacing: .02em;
  text-transform: none; color: var(--cc-ink-2); border-radius: 7px; white-space: nowrap;
}
:root[data-ui="atelier"] .at-drop a::after { display: none; }
:root[data-ui="atelier"] .at-drop a:hover { background: var(--cc-bg-soft); color: var(--cc-ink); }
/* A clicked navitem's dropdown vanishes at once; hover re-arms on re-entry. */
:root[data-ui="atelier"] .at-navitem.at-drop-lock .at-drop {
  opacity: 0 !important; visibility: hidden !important; transition: none;
}

/* Utility cluster: search pill, bell, support, gear. */
:root[data-ui="atelier"] .at-util { margin-left: auto; display: flex; align-items: center; gap: 9px; }
:root[data-ui="atelier"] .at-iconbtn {
  width: 36px; height: 36px; border: 1px solid var(--cc-line-strong, var(--cc-line));
  background: var(--cc-bg); border-radius: 999px; display: grid;
  place-items: center; cursor: pointer; color: var(--cc-ink-2);
  transition: border-color .15s, color .15s, box-shadow .15s; position: relative;
  padding: 0;
}
:root[data-ui="atelier"] .at-iconbtn:hover {
  border-color: var(--cc-gold); color: var(--cc-ink);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cc-gold) 12%, transparent);
}
:root[data-ui="atelier"] .at-iconbtn:focus-visible,
:root[data-ui="atelier"] .at-nav a:focus-visible,
:root[data-ui="atelier"] .at-subnav a:focus-visible,
:root[data-ui="atelier"] .at-textbtn:focus-visible,
:root[data-ui="atelier"] .at-lockup:focus-visible {
  outline: 2px solid var(--cc-gold); outline-offset: 2px;
}
/* The word buttons beside the icons — "Support", "Log out". Small caps, no
   box: the client template's masthead carries both and they must not become
   two more circles competing with the bell and the gear. */
:root[data-ui="atelier"] .at-textbtn {
  border: none; background: none; padding: 8px 4px; cursor: pointer;
  font-family: var(--cc-font-sans); font-size: 10.5px; font-weight: 600;
  letter-spacing: .18em; text-transform: uppercase; color: var(--cc-ink-3);
  transition: color .15s; white-space: nowrap;
}
:root[data-ui="atelier"] .at-textbtn:hover { color: var(--cc-ink); }
/* Unread count — a bare superscript numeral at the bell's shoulder. */
:root[data-ui="atelier"] .at-ncount {
  position: absolute; top: 1px; right: 4px; font-family: var(--cc-font-sans);
  font-size: 10px; line-height: 1; color: var(--cc-gold-bold); font-weight: 700;
  background: none; border: 0; padding: 0;
}

/* The masthead nav collapses on narrow windows (the phone bar + drawer keep
   serving navigation there). */
@media (max-width: 980px) {
  :root[data-ui="atelier"] .at-nav,
  :root[data-ui="atelier"] .at-subnav { display: none; }
}

/* ================= NOTICES WIRE ================= */
/* Mockup .wire: a hairlined strip — small-caps accent label, one rotating
   message, index dots, dismiss. Rotation is JS-driven; this is presentation.

   IT ALIGNS ITSELF WITH THE PAGE, because of where it is mounted. The wire
   renders inside AnnouncementBanner, which is a flex SIBLING of <main> and
   therefore spans the full window rather than the padded content column. Left
   alone it would start its label hard against the window edge while the hero
   below it began 48px in — the two most prominent lines on the page,
   misaligned.

   So it carries the SAME padding expression as Shell's PAGE_STYLE and the same
   max-width cap, which is why those numbers are repeated here rather than
   referenced: they belong to a JS style object this file cannot read. If the
   page gutter is ever retuned, this is its second home. The phone block near
   the foot of this file mirrors PAGE_PHONE_STYLE for the same reason. */
:root[data-ui="atelier"] .at-wire {
  display: flex; align-items: center; gap: 14px;
  padding: 10px clamp(16px, 3vw, 48px) 9px;
  /* width:100% is NOT redundant beside max-width. This is a flex ITEM in the
     shell's column, and it is itself display:flex — so without an explicit
     width it takes its shrink-to-fit content width and the strip renders as a
     short centred bar floating in the middle of the page, nowhere near the
     hero's left edge. Measured on the deployed preview, not reasoned about.
     The cap and the auto margins then centre the COLUMN on a wide monitor,
     exactly as PAGE_STYLE does for the content below. */
  width: 100%;
  max-width: 1600px; margin: 0 auto; box-sizing: border-box;
  border-bottom: 1px solid var(--cc-line);
}
@media (max-width: 700px) {
  :root[data-ui="atelier"] .at-wire { padding: 9px 12px 8px; gap: 10px; }
}
/* The body, when a notice has one: quieter than the title and the first thing
   to go when the strip runs out of room. */
:root[data-ui="atelier"] .at-wire-sub { color: var(--cc-ink-3); }
:root[data-ui="atelier"] .at-wire-lbl {
  font-size: 9px; letter-spacing: .32em; text-transform: uppercase;
  color: var(--cc-gold-bold); flex-shrink: 0; font-weight: 600;
}
:root[data-ui="atelier"] .at-wire-msg {
  flex: 1; min-width: 0; font-size: 12px; color: var(--cc-ink-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
:root[data-ui="atelier"] .at-wire-idx { display: flex; gap: 5px; flex-shrink: 0; }
:root[data-ui="atelier"] .at-wire-idx i {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--cc-line-strong, var(--cc-line));
}
:root[data-ui="atelier"] .at-wire-idx i.on { background: var(--cc-gold); }
:root[data-ui="atelier"] .at-wire-close {
  flex-shrink: 0; width: 20px; height: 20px; border: 1px solid var(--cc-line);
  background: none; border-radius: 50%; color: var(--cc-ink-3);
  font-size: 10px; line-height: 1; cursor: pointer;
  display: grid; place-items: center; padding: 0;
  transition: color .15s, border-color .15s;
}
:root[data-ui="atelier"] .at-wire-close:hover {
  color: var(--cc-ink); border-color: var(--cc-line-strong, var(--cc-line));
}
:root[data-ui="atelier"] .at-wire-close:focus-visible {
  outline: 2px solid var(--cc-gold); outline-offset: 2px;
}

/* ================= HERO ACTION PILLS (mockup .act) ================= */
:root[data-ui="atelier"] .at-act {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--cc-line-strong, var(--cc-line));
  background: var(--cc-bg); border-radius: 999px; padding: 8px 16px;
  font-size: 12.5px; font-weight: 600; color: var(--cc-ink); cursor: pointer;
  font-family: var(--cc-font-sans);
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
:root[data-ui="atelier"] .at-act:hover {
  border-color: var(--cc-gold);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cc-gold) 12%, transparent);
  transform: translateY(-1px);
}
:root[data-ui="atelier"] .at-act svg { color: var(--cc-gold-bold); }
/* The primary pill takes the INK, not the brand hue: it is the one filled
   control in the composition and the mockup's filled control is the ink
   itself. The client's primary already owns the masthead rule and every Save
   button; a third claim on it here would make the hero shout. */
:root[data-ui="atelier"] .at-act.at-act-primary {
  background: var(--cc-ink); border-color: var(--cc-ink); color: var(--cc-bg);
}
:root[data-ui="atelier"] .at-act.at-act-primary:hover {
  box-shadow: 0 4px 14px color-mix(in srgb, var(--cc-ink) 26%, transparent);
}
:root[data-ui="atelier"] .at-act.at-act-primary svg { color: var(--cc-bg); }
:root[data-ui="atelier"] .at-act:focus-visible {
  outline: 2px solid var(--cc-gold); outline-offset: 2px;
}

/* ================= THE FIGURES BAND ================= */
/* Mockup .figures: an OPEN band — no card, no fill — of hairline-separated
   cells, each a small-caps label over an oversized serif numeral over a quiet
   caption. Cells are buttons where they lead somewhere. */
:root[data-ui="atelier"] .at-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border-top: 1px solid var(--cc-line);
  border-bottom: 1px solid var(--cc-line);
  margin: 4px 0 22px;
}
:root[data-ui="atelier"] .at-fig {
  padding: 18px 20px; text-align: left; border-left: 1px solid var(--cc-line);
  background: none; font: inherit; color: inherit; cursor: default;
  transition: background .18s;
}
:root[data-ui="atelier"] .at-fig:first-child { border-left: 0; padding-left: 0; }
:root[data-ui="atelier"] button.at-fig { cursor: pointer; }
:root[data-ui="atelier"] button.at-fig:hover { background: var(--cc-bg-soft); }
:root[data-ui="atelier"] button.at-fig:focus-visible {
  outline: 2px solid var(--cc-gold); outline-offset: -2px;
}
:root[data-ui="atelier"] .at-fig-lbl {
  display: block; font-family: var(--cc-font-sans); font-size: 9.5px;
  font-weight: 600; letter-spacing: .26em; text-transform: uppercase;
  color: var(--cc-ink-3);
}
:root[data-ui="atelier"] .at-fig-val {
  display: block; font-family: var(--cc-font-display); font-weight: 400;
  font-size: 38px; line-height: 1.1; color: var(--cc-ink); margin-top: 8px;
  font-variant-numeric: lining-nums;
}
:root[data-ui="atelier"] .at-fig-cap {
  display: block; font-family: var(--cc-font-sans); font-size: 11px;
  color: var(--cc-ink-3); margin-top: 7px;
}

/* ================= THE DOSSIER ASSISTANT ================= */
/* The ask bar lights as ONE control when anything inside it takes focus. That
   cannot be written inline — :focus-within has no inline form — so it is
   hooked here on the panel's stable testid. Without it the bar is a box that
   contains a focused input while looking exactly as it did at rest, which is
   the tell that a composed control is really four controls in a row. */
:root[data-ui="atelier"] [data-testid="dossier-assistant"] form:focus-within {
  border-color: var(--cc-gold);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cc-gold) 12%, transparent);
}
:root[data-ui="atelier"] [data-testid="dossier-assistant"] form {
  transition: border-color .15s, box-shadow .15s;
}
/* The glyph buttons are borderless at rest, so they need a hover ground to be
   discoverable as buttons at all. Not applied while they are live — a filled
   accent does not want a wash over it. */
:root[data-ui="atelier"] [data-testid="assistant-mic"]:hover,
:root[data-ui="atelier"] [data-testid="assistant-converse"]:hover {
  background: var(--cc-bg-soft);
  color: var(--cc-ink);
}
:root[data-ui="atelier"] [data-testid="assistant-mic"][aria-pressed="true"]:hover,
:root[data-ui="atelier"] [data-testid="assistant-converse"][aria-pressed="true"]:hover {
  background: inherit; color: inherit;
}
:root[data-ui="atelier"] [data-testid="assistant-ask"]:not(:disabled):hover {
  box-shadow: 0 4px 14px color-mix(in srgb, var(--cc-ink) 24%, transparent);
}

/* ================= SEGMENTED CONTROLS + PAGERS =================
   The two segmented controls in the product — the calendar's Day/Week/Month
   and Settings' text size — plus the calendar's pager. Both were written as
   6px rectangles with a solid accent fill on the selected item, which is the
   only remaining control shape on these pages that is not a pill.

   Hooked on stable testids rather than restyled in place, for two reasons: the
   selected/unselected colours are computed inline from the palette (so this
   layer only has to change the SHAPE and let the colour through), and the
   files they live in are core, where an inline edit is a hand-edited-core
   finding rather than a skin.

   !important is deliberate and confined: these fight inline styles, and no
   classic session carries data-ui, so none of it can leak. */
:root[data-ui="atelier"] [data-testid^="calendar-view-"],
:root[data-ui="atelier"] [data-testid^="settings-text-size-"] {
  border-radius: 999px !important;
}
/* The pager: three equal round controls, so ← Today → reads as one object
   rather than two squares either side of a wider one. */
:root[data-ui="atelier"] [data-testid="calendar-prev"],
:root[data-ui="atelier"] [data-testid="calendar-next"],
:root[data-ui="atelier"] [data-testid="calendar-today"] {
  border-radius: 999px !important;
  border-color: var(--cc-line-strong, var(--cc-line)) !important;
}
:root[data-ui="atelier"] [data-testid="calendar-prev"]:hover,
:root[data-ui="atelier"] [data-testid="calendar-next"]:hover,
:root[data-ui="atelier"] [data-testid="calendar-today"]:hover {
  border-color: var(--cc-gold) !important;
}

/* The operator-contact CTA in the page footer. Its FILL stays the client's
   navy — that is a deliberate decision recorded in OperatorContact.jsx (primary
   is otherwise nearly invisible on a Command Center, and this button is on
   every route), and the palette engine pins the navy role's lightness so white
   on it is safe whatever primary the client picked. Only the shape changes, so
   it stops being the last rectangle in a product of pills. */
:root[data-ui="atelier"] [data-testid="operator-contact-toggle"] {
  border-radius: 999px !important;
}

/* NO BLANKET `main button:hover` RULE HERE, deliberately. It is the obvious
   way to give the new hairline pills a hover — and it would also repaint the
   border of every calendar day cell, every glyph button in the assistant and
   every toggle, all of which are buttons too and none of which wants a gold
   edge. A hover state that is right on eight controls and wrong on forty is a
   worse design than no hover state. The pills that need one ask for it by
   testid, above and below. */

/* ================= INTERIOR IDIOM LAYER =================
   The preview's interior vocabulary applied over inline-styled components
   through their STABLE hooks (testids, element selectors). !important is
   deliberate: these fight inline styles, and this is a skin layer confined to
   this file and this profile — a classic session carries no data-ui, so none
   of it can leak. */

/* .mh — the quiet small-caps panel head. The dashboard panels print a centred
   serif title; the Atelier head is a quiet sans label that lets the panel's
   CONTENT be the loud thing. */
:root[data-ui="atelier"] [data-testid^="panel-"] > h3 {
  font-family: var(--cc-font-sans) !important;
  font-size: 10px !important;
  letter-spacing: .26em !important;
  text-transform: uppercase !important;
  color: var(--cc-ink-3) !important;
  font-weight: 700 !important;
  text-align: left !important;
}

/* .tbl — every data table reads as the preview's table. */
:root[data-ui="atelier"] main table { border-collapse: collapse !important; }
:root[data-ui="atelier"] main table th {
  text-align: left;
  font-size: 9.5px !important;
  letter-spacing: .22em !important;
  text-transform: uppercase !important;
  color: var(--cc-ink-3) !important;
  font-weight: 700 !important;
  padding: 10px 12px !important;
  border-bottom: 1px solid var(--cc-line-strong, var(--cc-line)) !important;
  background: transparent !important;
}
:root[data-ui="atelier"] main table td {
  padding: 12px !important;
  border-bottom: 1px solid var(--cc-line) !important;
  background: transparent !important;
}
:root[data-ui="atelier"] main table tr:last-child td { border-bottom: 0 !important; }

/* .pinput — every page-level search input becomes the round pill. */
:root[data-ui="atelier"] main input[type="search"] {
  border-radius: 999px !important;
  border: 1px solid var(--cc-line-strong, var(--cc-line)) !important;
  padding: 8px 15px !important;
  background: var(--cc-bg) !important;
}
:root[data-ui="atelier"] main input[type="search"]:focus {
  outline: none;
  border-color: var(--cc-gold) !important;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cc-gold) 14%, transparent) !important;
}

/* The page HEAD on an interior page — mockup .agenthead: an oversized serif
   name over a quiet blurb, with the section rule beneath. Hooked on the
   client-page heading rather than a class, so a bespoke page written before
   this existed still takes the idiom. */
:root[data-ui="atelier"] main > div > div > h1,
:root[data-ui="atelier"] main h1 {
  font-family: var(--cc-font-display) !important;
  font-weight: 400 !important;
  letter-spacing: .004em !important;
}

/* ================= SEARCH OVERLAY (⌘K) ================= */
:root[data-ui="atelier"] .at-scrim {
  position: absolute; inset: 0;
  background: color-mix(in srgb, var(--cc-ink) 34%, transparent);
  backdrop-filter: blur(2px);
}
:root[data-ui="atelier"] .at-searchov { position: fixed; inset: 0; z-index: 85; }
:root[data-ui="atelier"] .at-spanel {
  position: relative; margin: 11vh auto 0; width: min(580px, 92vw);
  background: var(--cc-bg); border: 1px solid var(--cc-line);
  border-radius: 16px; padding: 10px; box-sizing: border-box;
  max-height: 70vh; overflow: auto;
  box-shadow: var(--at-shadow-pop);
}
:root[data-ui="atelier"] .at-sinput {
  width: 100%; box-sizing: border-box; border: 0;
  border-bottom: 1px solid var(--cc-line); border-radius: 0; padding: 14px 12px;
  font-family: var(--cc-font-sans); font-size: 15px; color: var(--cc-ink);
  background: transparent;
}
:root[data-ui="atelier"] .at-sinput:focus { outline: none; border-bottom-color: var(--cc-gold); }
:root[data-ui="atelier"] .at-sgroup {
  font-size: 9px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--cc-gold-bold); font-weight: 700; padding: 14px 12px 5px;
}
:root[data-ui="atelier"] .at-srow {
  display: block; width: 100%; text-align: left; padding: 9px 12px;
  border-radius: 9px; border: none; background: transparent; cursor: pointer;
  font-family: var(--cc-font-sans); color: inherit;
}
:root[data-ui="atelier"] .at-srow:hover,
:root[data-ui="atelier"] .at-srow:focus-visible { background: var(--cc-bg-soft); }
:root[data-ui="atelier"] .at-srow b { display: block; font-size: 13px; font-weight: 600; color: var(--cc-ink); }
:root[data-ui="atelier"] .at-srow span { font-size: 11px; color: var(--cc-ink-3); }

/* The masthead search pill (mockup .search). */
:root[data-ui="atelier"] .at-search {
  display: flex; align-items: center; gap: 9px;
  border: 1px solid var(--cc-line-strong, var(--cc-line));
  border-radius: 999px; padding: 8px 15px; color: var(--cc-ink-3);
  font-size: 12.5px; min-width: 190px; background: var(--cc-bg);
  transition: border-color .15s, box-shadow .15s; cursor: text;
  font-family: var(--cc-font-sans);
}
:root[data-ui="atelier"] .at-search:hover {
  border-color: var(--cc-gold);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cc-gold) 12%, transparent);
}
:root[data-ui="atelier"] .at-search kbd {
  margin-left: auto; font-family: var(--cc-font-mono); font-size: 10px;
  border: 1px solid var(--cc-line); border-radius: 4px; padding: 1px 5px;
}
@media (max-width: 1240px) {
  :root[data-ui="atelier"] .at-search { display: none; }
}

/* ================= PHONE BAR + DRAWER ================= */
:root[data-ui="atelier"] .at-mbar {
  display: flex; align-items: center; gap: 11px;
  padding: 12px 16px; padding-top: calc(12px + env(safe-area-inset-top));
  background: var(--cc-bg); border-top: 3px solid var(--cc-navy);
  border-bottom: 1px solid var(--cc-line);
  position: relative; z-index: 40; flex-shrink: 0;
}
:root[data-ui="atelier"] .at-mbar-home {
  flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center;
  gap: 8px; background: transparent; border: none; padding: 0; cursor: pointer;
}
:root[data-ui="atelier"] .at-mbar-word {
  font-family: var(--cc-font-wordmark, var(--cc-font-display)); font-weight: 600;
  font-size: 11px; letter-spacing: .24em; text-transform: uppercase;
  padding-left: .24em; color: var(--cc-ink); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
:root[data-ui="atelier"] .at-drawer {
  position: fixed; inset: 0; z-index: 70;
  visibility: hidden; transition: visibility 0s .32s;
}
:root[data-ui="atelier"] .at-drawer.at-open { visibility: visible; transition-delay: 0s; }
:root[data-ui="atelier"] .at-drawer .at-scrim { opacity: 0; transition: opacity .28s; }
:root[data-ui="atelier"] .at-drawer.at-open .at-scrim { opacity: 1; }
:root[data-ui="atelier"] .at-dpanel {
  position: absolute; top: 0; bottom: 0; left: 0; width: min(292px, 82vw);
  background: var(--cc-bg); border-right: 1px solid var(--cc-line);
  padding: calc(16px + env(safe-area-inset-top)) 12px calc(16px + env(safe-area-inset-bottom));
  overflow-y: auto; box-sizing: border-box;
  transform: translateX(-102%); transition: transform .32s cubic-bezier(.2,.7,.2,1);
}
:root[data-ui="atelier"] .at-drawer.at-open .at-dpanel { transform: none; }
:root[data-ui="atelier"] .at-dhead {
  display: flex; align-items: center; gap: 10px;
  padding: 0 8px 16px; border-bottom: 1px solid var(--cc-line); margin-bottom: 10px;
}
:root[data-ui="atelier"] .at-dhead span {
  font-family: var(--cc-font-wordmark, var(--cc-font-display)); font-size: 11px;
  letter-spacing: .22em; text-transform: uppercase; color: var(--cc-ink);
  flex: 1; min-width: 0;
}
:root[data-ui="atelier"] .at-dclose { width: 30px; height: 30px; font-size: 11px; }
:root[data-ui="atelier"] .at-dpanel nav a {
  display: block; padding: 12px 10px; font-size: 13px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--cc-ink-2); text-decoration: none;
  border-radius: 8px;
}
:root[data-ui="atelier"] .at-dpanel nav a:hover { background: var(--cc-bg-soft); color: var(--cc-ink); }
:root[data-ui="atelier"] .at-dpanel nav a[aria-current] {
  color: var(--cc-ink); box-shadow: inset 2px 0 0 var(--cc-gold); background: var(--cc-bg-soft);
}
:root[data-ui="atelier"] .at-dgroup {
  font-size: 8.5px; letter-spacing: .3em; text-transform: uppercase;
  color: var(--cc-gold-bold); font-weight: 700; padding: 16px 10px 6px;
}

/* ================= BOTTOM-SHEET MODALS (phone) ================= */
:root[data-ui="atelier"] .at-sheet { animation: at-sheet-up .32s cubic-bezier(.2,.7,.2,1); }
:root[data-ui="atelier"] .at-sheet::before {
  content: ''; display: block; width: 36px; height: 4px; border-radius: 2px;
  background: var(--cc-line-strong, var(--cc-line)); margin: 0 auto 14px;
}
@keyframes at-sheet-up { from { transform: translateY(105%); } to { transform: none; } }

/* ================= CLIENT ROSTER CARDS ================= */
/* The lift-on-hover the mockup gives a board card. Hooked on the stable
   testid so the component needs no class plumbing. */
:root[data-ui="atelier"] [data-testid^="client-card"],
:root[data-ui="atelier"] [data-testid="clients-card"] {
  transition: transform .25s cubic-bezier(.2,.7,.2,1), box-shadow .25s;
}
:root[data-ui="atelier"] [data-testid^="client-card"]:hover,
:root[data-ui="atelier"] [data-testid="clients-card"]:hover {
  transform: translateY(-4px);
  box-shadow: var(--at-shadow-pop);
}

/* ================= MOBILE HOME ================= */
@media (max-width: 700px) {
  /* Hero: the mobile template's tighter scale. */
  :root[data-ui="atelier"] [data-testid="atelier-hero"] h1 {
    font-size: clamp(32px, 9.5vw, 42px) !important;
  }
  :root[data-ui="atelier"] [data-testid="atelier-hero"] .at-welcome {
    font-size: 16.5px !important;
  }
  /* Action pills ride one edge-to-edge scrolling row (template .actions). */
  :root[data-ui="atelier"] [data-testid="atelier-hero"] .at-actions {
    flex-wrap: nowrap !important;
    overflow-x: auto;
    scrollbar-width: none;
    margin: 0 calc(-1 * clamp(14px, 3vw, 44px));
    padding-left: clamp(14px, 3vw, 44px) !important;
    padding-right: clamp(14px, 3vw, 44px) !important;
  }
  :root[data-ui="atelier"] [data-testid="atelier-hero"] .at-actions::-webkit-scrollbar {
    display: none;
  }
  :root[data-ui="atelier"] [data-testid="atelier-hero"] .at-actions .at-act {
    flex-shrink: 0; white-space: nowrap;
  }
  /* Figures 2-up, each stacked row taking its own hairline and the left-edge
     cells of the lower rows dropping the column rule. */
  :root[data-ui="atelier"] .at-figures { grid-template-columns: 1fr 1fr; }
  :root[data-ui="atelier"] .at-fig { padding: 14px 14px; }
  :root[data-ui="atelier"] .at-fig:nth-child(odd) { border-left: 0; padding-left: 0; }
  :root[data-ui="atelier"] .at-fig:nth-child(n+3) { border-top: 1px solid var(--cc-line); }
  :root[data-ui="atelier"] .at-fig-val { font-size: 34px; }
}

@media (prefers-reduced-motion: reduce) {
  :root[data-ui="atelier"] .at-veil { display: none; }
  :root[data-ui="atelier"] .at-nav a::after,
  :root[data-ui="atelier"] .at-subnav a::after,
  :root[data-ui="atelier"] .at-drop { transition: none; }
  :root[data-ui="atelier"] [data-testid^="client-card"],
  :root[data-ui="atelier"] [data-testid="clients-card"] { transition: none; }
  :root[data-ui="atelier"] [data-testid^="client-card"]:hover,
  :root[data-ui="atelier"] [data-testid="clients-card"]:hover { transform: none; }
  :root[data-ui="atelier"] .at-dpanel { transition: none; }
  :root[data-ui="atelier"] .at-drawer .at-scrim { transition: none; }
  :root[data-ui="atelier"] .at-sheet { animation: none; }
  :root[data-ui="atelier"] .at-act:hover { transform: none; }
}
/* Command Center — interaction layer.
 *
 * DESIGN SAMPLE 3 — "The Study" (executive briefing-room dark theme).
 * Hover/motion retuned to the dark charcoal + brass palette; structure and
 * class names unchanged.
 *
 * Scoped TIGHTLY to what inline styles cannot express: :hover states,
 * transitions, and @keyframes. Imported once from src/main.jsx.
 */

/* --------------------------------------------------------------------------
 * Keyframes — live status dots
 * ------------------------------------------------------------------------ */
@keyframes cc-pulse-dot {
  0%, 100% { box-shadow: 0 0 0 3px rgba(95, 158, 125, 0.22); }
  50%      { box-shadow: 0 0 0 5px rgba(95, 158, 125, 0.1); }
}

.cc-live-dot {
  animation: cc-pulse-dot 2s ease-in-out infinite;
}
.cc-live-pulse {
  animation: cc-pulse-dot 1.8s ease-in-out infinite;
}

/* --------------------------------------------------------------------------
 * Masthead nav links + roster medallions
 * ------------------------------------------------------------------------ */
.cc-masthead-link {
  transition: color 0.15s, border-color 0.15s;
}
.cc-masthead-link:hover {
  color: var(--cc-accent-hi);
}

.cc-medallion {
  transition: transform 0.18s, filter 0.18s;
}
.cc-medallion:hover {
  transform: translateY(-3px);
  filter: drop-shadow(0 6px 14px rgba(var(--cc-accent-tint-rgb), 0.25));
}
.cc-medallion:hover span:first-of-type {
  color: var(--cc-accent-hi);
}

/* --------------------------------------------------------------------------
 * Top bar buttons + member pill
 * ------------------------------------------------------------------------ */
.cc-top-btn,
.cc-member-pill {
  transition: background 0.15s, border-color 0.15s;
}
.cc-top-btn:hover,
.cc-member-pill:hover {
  border-color: var(--cc-accent-line);
  background: rgba(var(--cc-accent-tint-rgb), 0.14);
}

/* Sticky agent ribbon removed 2026-07-23 (it leaked across page
   navigations). Its classes (.cc-sticky-ribbon / .cc-ribbon-*) are
   intentionally gone; the roster grid is the sole agent-nav surface. */

/* --------------------------------------------------------------------------
 * Agents grid — tile hover lift + brass top-border scaleX reveal
 * ------------------------------------------------------------------------ */
.cc-agent-tile {
  transition: border-color 0.18s, transform 0.18s, box-shadow 0.18s, color 0.18s;
}
.cc-agent-tile::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--cc-accent-line);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.18s;
}
.cc-agent-item:hover .cc-agent-tile {
  border-color: var(--cc-accent-line-2);
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5);
  color: var(--cc-accent-hi);
}
.cc-agent-item:hover .cc-agent-tile::before {
  transform: scaleX(1);
}

/* --------------------------------------------------------------------------
 * Quick Actions — primary + secondary button hovers
 * ------------------------------------------------------------------------ */
.cc-qa-primary {
  transition: background 0.15s, border-color 0.15s;
}
.cc-qa-primary:hover {
  background: #33466a;
  border-color: var(--cc-accent-line);
}
.cc-qa-btn {
  transition: background 0.15s, border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.cc-qa-btn:hover {
  background: #33466a;
  border-color: var(--cc-accent-line);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.45);
}
.cc-qa-arrow {
  transition: transform 0.15s, color 0.15s;
}
.cc-qa-btn:hover .cc-qa-arrow {
  color: var(--cc-accent-hi);
  transform: translateX(2px);
}


/* --------------------------------------------------------------------------
 * Sign-offs — approve / reject buttons
 * ------------------------------------------------------------------------ */
.cc-signoff-btn {
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.cc-signoff-btn-approve:hover { background: #4c8467; }
.cc-signoff-btn-reject:hover  { border-color: #b0413e; color: #cd6a63; }

/* --------------------------------------------------------------------------
 * Needs Attention — item row hover
 * ------------------------------------------------------------------------ */
.cc-attn-item {
  transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}
.cc-attn-item:hover {
  transform: translateX(2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  border-color: var(--cc-accent-line-2);
}

/* --------------------------------------------------------------------------
 * Live Activity — event row hover
 * ------------------------------------------------------------------------ */
.cc-activity-row {
  transition: background 0.12s;
}
.cc-activity-row:hover {
  background: rgba(var(--cc-accent-tint-rgb), 0.06);
}

/* Messages panel search — placeholder + clear button on the dark title bar. */
[data-testid="messages-search"]::placeholder {
  color: rgba(255, 255, 255, 0.5);
}
[data-testid="messages-search"]::-webkit-search-cancel-button {
  filter: invert(1);
  opacity: 0.5;
  cursor: pointer;
}

/* --------------------------------------------------------------------------
 * Week Calendar — day cell hover (today cell keeps its slate fill)
 * ------------------------------------------------------------------------ */
.cc-week-day {
  transition: border-color 0.15s, background 0.15s;
}
.cc-week-day:hover {
  border-color: var(--cc-accent-line);
}
/* Today's cell is a soft gold wash set inline per cell (2026-07-23), no longer
   a navy fill; this only carries its gold hover border. */
.cc-week-day.is-today:hover {
  border-color: var(--cc-gold, var(--cc-accent-line));
}

/* --------------------------------------------------------------------------
 * Generic agent-tile / cost-row / signoff-item — subtle shared hovers
 * ------------------------------------------------------------------------ */
.cc-hoverable {
  transition: background 0.15s, border-color 0.15s;
}

/* --------------------------------------------------------------------------
 * Masthead BB monogram — the asset is a black-on-transparent PNG, invisible on
 * the dark masthead. In dark mode recolor it to white (brightness(0) forces the
 * silhouette solid black preserving alpha, invert(1) flips black -> white).
 * Light mode leaves the original black lockup on the cream masthead untouched.
 *
 * ⚠ EXCLUDES THE CLIENT LOGO (1.13.0). This rule was written when the mark was
 * a PNG; the mark became TYPE in 1.2.0 and the selector has matched nothing
 * since. Adding the client-logo <img> in 1.13.0 silently reactivated it, and
 * the result was a brand mark recoloured to a white silhouette in dark mode —
 * every colour in the client's logo destroyed, and, combined with the white
 * plate behind it, white-on-white and completely invisible. Caught by a
 * screenshot; no test would have seen it, because the bug is a stylesheet
 * meeting a component that did not exist when it was written.
 *
 * A client's logo keeps its own colours. Legibility in dark mode is the
 * plate's job (BrandMark.jsx) or a supplied `branding.logo.dark`, and both
 * preserve the artwork instead of flattening it to a silhouette.
 * ------------------------------------------------------------------------ */
:root[data-theme="dark"] [data-testid="header-home-logo"] img:not([data-testid="brand-logo"]) {
  filter: brightness(0) invert(1);
}

/* --------------------------------------------------------------------------
 * Header focus rings — dark surfaces take a brass ring
 * ------------------------------------------------------------------------ */
[data-testid="header-home-logo"]:focus-visible,
[data-testid="header-home-title"]:focus-visible,
[data-testid="feedback-button"]:focus-visible,
[data-testid="header-notif-btn"]:focus-visible,
[data-testid="mobile-nav-toggle"]:focus-visible,
[data-testid="member-switcher"]:focus-visible {
  outline: 2px solid var(--cc-gold-bold, var(--cc-accent-line));
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
 * Stat band — clickable figure cells (tickets → Feedback, tasks → Tasks,
 * spend → Costs). Subtle tint + focus ring; the repo cell is static.
 * ------------------------------------------------------------------------ */
.cc-stat-cell {
  transition: background 0.15s;
}
.cc-stat-cell:hover {
  background: rgba(var(--cc-gold-rgb), 0.07);
}
.cc-stat-cell:focus-visible {
  outline: 2px solid var(--cc-gold-bold, var(--cc-accent-line));
  outline-offset: -2px;
}

/* --------------------------------------------------------------------------
 * Mobile masthead / drawer BB mark — same black-on-transparent PNG as the
 * desktop lockup, so recolor it to white in dark mode.
 *
 * ⚠ The filter sits on the WRAPPER, not the image, so it cannot be undone from
 * the inside — an ancestor filter has already rasterised by the time an inner
 * rule is considered. Header.jsx therefore stops applying `cc-mobile-mark`
 * when the mark is an image (see markIsType()), which is the only place the
 * distinction can be made. Same 1.13.0 reasoning as the desktop rule above.
 * ------------------------------------------------------------------------ */
:root[data-theme="dark"] .cc-mobile-mark {
  filter: brightness(0) invert(1);
}

/* --------------------------------------------------------------------------
 * Mobile nav drawer — scrim fade + panel slide-in
 * ------------------------------------------------------------------------ */
@keyframes cc-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes cc-drawer-in {
  from { transform: translateX(-100%); }
  to   { transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  [data-testid="mobile-nav-drawer"],
  [data-testid="mobile-nav-scrim"] {
    animation: none !important;
  }
}

/* --------------------------------------------------------------------------
 * Skip-link + surface focus rings
 * ------------------------------------------------------------------------ */
.cc-skip-link {
  position: absolute;
  top: -40px;
  left: 8px;
  padding: 8px 16px;
  background: var(--cc-navy, #2a3a58);
  color: #ece7dc;
  border-radius: 4px;
  z-index: 10000;
  text-decoration: none;
  font-family: var(--cc-font-sans, system-ui);
  font-size: 13px;
}
.cc-skip-link:focus,
.cc-skip-link:focus-visible {
  top: 8px;
  outline: 2px solid var(--cc-gold-bold, var(--cc-accent-line));
  outline-offset: 2px;
}

[data-testid^="goal-row-"]:focus-visible,
[data-testid^="feedback-row-"]:focus-visible,
[data-testid^="feedback-bucket-header-"]:focus-visible,
[role="menuitem"]:focus-visible {
  outline: 2px solid var(--cc-gold-bold, var(--cc-accent-line));
  outline-offset: 2px;
}

/* Dashboard month calendar — day cells are only interactive when a bespoke
   `calendar` page exists to receive the click (CalendarPanel renders a <div>
   otherwise, which these rules never match). The hover is a tint rather than a
   border so the grid's rules stay unbroken as the cursor crosses it. */
.cc-cal-day {
  transition: background 0.12s;
}
.cc-cal-day:hover {
  background: rgba(var(--cc-accent-tint-rgb), 0.14);
}
.cc-cal-day:focus-visible {
  outline: 2px solid var(--cc-gold-bold, var(--cc-accent-line));
  outline-offset: -2px;
}

/* --------------------------------------------------------------------------
 * Settings — the interaction layer for the /settings register.
 *
 * SettingsPage.jsx styles itself inline (the house convention), which cannot
 * express :focus-visible, a hover gated on pointer type, or reduced motion.
 * Those three live here and nowhere else. Every colour is a --cc-* token, so
 * this block reskins with each client's generated palette like the rest.
 * ------------------------------------------------------------------------ */

/* Hover is an enhancement, never a carrier of information — and a :hover style
   that survives on a touch device sticks after a tap. Gate it on a real mouse. */
@media (hover: hover) and (pointer: fine) {
  .cc-set-btn:hover:not(:disabled) {
    background: rgba(var(--cc-gold-rgb), 0.08);
  }
  .cc-set-rail-link:hover {
    color: var(--cc-ink);
    border-left-color: var(--cc-gold);
  }
  .cc-set-switch:hover:not(:disabled) > span {
    filter: brightness(0.96);
  }
}

/* Every control on the page takes the same ring. outline-offset keeps it clear
   of the switch track and the sheet's own border rather than sitting on top of
   either. */
.cc-set-btn:focus-visible,
.cc-set-switch:focus-visible,
.cc-set-input:focus-visible,
.cc-set-rail-link:focus-visible,
[data-testid^="settings-brand-"]:focus-visible {
  outline: 2px solid var(--cc-gold-bold, var(--cc-accent-line));
  outline-offset: 2px;
}

/* A focused text field also reads as focused without the ring — the border is
   what someone tracks while typing. */
.cc-set-input:focus {
  border-color: var(--cc-gold);
}

.cc-set-btn,
.cc-set-rail-link {
  transition: background 150ms cubic-bezier(0.2, 0, 0, 1),
              color 150ms cubic-bezier(0.2, 0, 0, 1),
              border-color 150ms cubic-bezier(0.2, 0, 0, 1);
}

/* Reduced motion means less movement, not less information: the switch still
   changes fill and the knob is still in the other place — it just gets there
   without travelling, and the rail jump stops animating. */
@media (prefers-reduced-motion: reduce) {
  .cc-set-btn,
  .cc-set-rail-link,
  .cc-set-switch > span,
  .cc-set-switch > span > span {
    transition-duration: 1ms !important;
  }
  [data-testid="settings-page"] {
    scroll-behavior: auto !important;
  }
}
/*$vite$:1*/