/* ═══════════════════════════════════════════════════════════════════════════
   STYLE THEMES — the second theme axis
   ═══════════════════════════════════════════════════════════════════════════

   A colour theme answers "what hue is this app?". A style theme answers "what
   is it MADE of?" — how sharp the corners are, whether surfaces float or sit
   flat, how heavy the borders are, whether things look pressed, glazed or
   printed. The two are independent: Brutalism in Claude orange is as valid a
   combination as Glassmorphism in Discord blurple.

   THREE RULES THIS FILE KEEPS
   ---------------------------
   1. NOTHING HERE APPLIES BY DEFAULT. Every rule is scoped under
      html[data-style-theme="<name>"], and there is deliberately no block for
      "default". The app's existing look IS the default and this file cannot
      touch it — which is also what makes the feature safe to ship on a live
      site: choosing nothing changes nothing.

   2. STYLE THEMES NEVER SET COLOUR. They set radius, elevation, border weight,
      surface treatment and type — never hue. Without that rule the matrix is
      11 styles x 14 colour themes x 3 modes = 462 combinations to keep
      coherent. With it, a style composes with whatever colour and light/dark
      mode is already active, and there are 11 blocks to maintain.

   3. TOKENS FIRST, EXCEPTIONS AFTER. Each theme sets the --st-* tokens (their
      defaults live in tokens.css) and the application layer below maps those
      onto the components that carry the app's identity. Only the four themes
      that genuinely cannot be expressed as tokens — glass blur, neumorphic
      double shadows, skeuomorphic bevels, post-modern asymmetry — add rules of
      their own, and each says why.

   WHAT IS DELIBERATELY NOT COVERED
   --------------------------------
   The stylesheets carry ~780 hardcoded border-radius/box-shadow declarations.
   The component families below account for roughly a quarter of them and
   essentially all of the visual identity; the rest are one-off decorations
   (icon chips, tiny badges, the scroll-to-bottom pill) where a theme not
   reaching them goes unnoticed. Brutalism therefore leaves a few small pieces
   of chrome rounded. That is an accepted trade, not an oversight — the
   alternative was rewriting every stylesheet in the app.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ───────────────────────────────────────────────────────────────────────────
   APPLICATION LAYER
   Maps the tokens onto components. Scoped to "a style theme is active", so it
   is inert until one is chosen.

   MATCHED STRUCTURALLY, NOT BY NAME. The first version of this listed about
   fifteen classes by hand and the result was a themed message area sitting
   next to an untouched sidebar, search box and menus - which looked broken
   rather than styled. The app has 73 classes ending in -btn, 37 in -card, 25
   in -item, 23 in -badge and so on; no hand-kept list survives contact with
   that. Suffix matching reaches all of them, including components added later,
   which is the only way this stays true as the app grows.

   Groups are ordered least- to most-specific so a later one wins the tie: a
   .export-menu-item is an item, not a menu, and reads that way because the
   item group comes after the surface group.

   !important throughout, reluctantly and on purpose: this is by definition the
   last layer, and what it overrides is spread across eight stylesheets with
   mixed specificity (including their own !important on the mobile rules).
   Without it the layer would win in some places and lose in others, which is
   worse than either.
   ─────────────────────────────────────────────────────────────────────────── */

html[data-style-theme]:not([data-style-theme="default"]) {
  /* Type is a fallback only. The user's own font-family preference is set
     inline on <html> and continues to win - a style theme suggests a face, it
     does not seize one. */
  font-family: var(--st-font-stack, inherit);

  /* THE APP'S OWN TOKENS FOLLOW THE STYLE THEME.
     ~98 declarations across the stylesheets already say var(--r-sm) or
     var(--shadow-2) rather than a literal - the settings nav, auth cards,
     landing sections, ui.css throughout. Pointing those tokens at the style
     tokens themes every one of them with no selector matching at all, which is
     exactly how a colour theme reaches the whole app from three variables.
     Anything already written properly gets this for free.

     Scoped to a non-default theme, so the values in tokens.css remain the
     truth when no style is chosen. --radius, --shadow-sm and --shadow are
     legacy aliases of these and follow automatically. --shadow-accent is left
     alone: it is derived from the colour, and colour is not ours to set. */
  --r-sm:   var(--st-radius-sm);
  --r-md:   var(--st-radius-md);
  --r-lg:   var(--st-radius-lg);
  --r-xl:   var(--st-radius-lg);
  --r-full: var(--st-radius-pill);
  --shadow-1: var(--st-elev-1);
  --shadow-2: var(--st-elev-2);
  --shadow-3: var(--st-elev-3);
  --shadow-4: var(--st-elev-3);
}

/* ── 1. Surfaces — anything that holds content and reads as a panel ── */
html[data-style-theme]:not([data-style-theme="default"]) :is(
  [class*="-card"], [class="card"], [class*="-panel"], [class*="popover"],
  [class*="-menu"], [class*="-sheet"],
  .modal-content, .acct-section, .msg-bubble, .reasoning-panel,
  .citation-strip, .dropdown, .sam-menu, .slash-menu,
  /* -wrap is the one suffix that means two different things here: a visible
     control box (the sidebar search) and an invisible page container
     (.admin-wrap, .page-wrap, .settings-wrap). Matching it wholesale would put
     a 24px radius and a drop shadow around whole pages, so the control boxes
     are named and the containers are left alone. */
  .session-search-wrap, .hist-search-wrap, .input-icon-wrap,
  .persona-select-wrap, .mts-model-wrap, .draw-extra-wrap, .draw-neg-wrap
) {
  border-radius: var(--st-radius-lg) !important;
  box-shadow: var(--st-elev-2) !important;
  border-width: var(--st-border-width) !important;
}

/* ── 2. Bars and strips — full-width regions inside a panel.
       Elevation but no rounding: a strip that spans its container edge to edge
       looks broken with corners on it. ── */
html[data-style-theme]:not([data-style-theme="default"]) :is(
  [class*="-bar"], [class*="-strip"], [class*="toolbar"],
  .app-sidebar, .mobile-topbar, .chat-input-wrap
) {
  border-radius: 0 !important;
  box-shadow: var(--st-elev-1) !important;
  border-width: var(--st-border-width) !important;
}

/* ── 3. Controls — everything you click or type into ── */
html[data-style-theme]:not([data-style-theme="default"]) :is(
  button, [class*="-btn"], [class="btn"], .btn,
  [class*="-toggle"], [class*="-close"],
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]),
  select, textarea
) {
  border-radius: var(--st-radius-md) !important;
  box-shadow: var(--st-elev-1) !important;
  border-width: var(--st-border-width) !important;
  transition: var(--st-transition) !important;
}

/* ── 4. List rows — sidebar chats, folders, projects, menu entries.
       After the surface group on purpose: .export-menu-item is an item. ── */
html[data-style-theme]:not([data-style-theme="default"]) :is(
  .session-search-wrap, .hist-search-wrap, .input-icon-wrap
) {
  /* Overrides the surface radius above: these are control boxes, and the
     sidebar search in particular is a 100px stadium by default, which survives
     everything unless it is told the control radius explicitly. */
  border-radius: var(--st-radius-md) !important;
  box-shadow: var(--st-elev-1) !important;
}

html[data-style-theme]:not([data-style-theme="default"]) :is(
  [class*="-item"], .session-item, .project-item, .folder-item,
  /* Nav links behave as rows, not buttons - .settings-nav-link,
     .admin-nav-link. Radius follows the theme; elevation would make a sidebar
     of them look like a stack of floating cards. */
  [class*="-nav-link"], [class*="-tab"]
) {
  border-radius: var(--st-radius-md) !important;
  box-shadow: none !important;
  transition: var(--st-transition) !important;
}

/* ── 5. Pills and badges — small, fully rounded by default. A theme that
       squares everything else has to square these too, or the intent reads as
       an oversight rather than a decision. ── */
html[data-style-theme]:not([data-style-theme="default"]) :is(
  [class*="-pill"], [class*="-chip"], [class="chip"], .chip,
  [class*="-badge"], [class="badge"], .badge, .model-badge, .msg-avatar
) {
  border-radius: var(--st-radius-pill) !important;
  border-width: var(--st-border-width) !important;
}

/* ── 6. Things that must keep their own shape regardless of theme.
       A spinner is a circle because it spins; a progress track reads as a
       measurement, not a component. Squaring either is a bug, not a style. ── */
html[data-style-theme]:not([data-style-theme="default"]) :is(
  .spinner, [class*="-spinner"], .tc-preview, .sc-swatch,
  #ctx-meter-track, #ctx-meter-fill, [class*="-track"], [class*="-fill"]
) {
  border-radius: revert !important;
  box-shadow: revert !important;
}

/* ── 7. CONTRAST GUARD — never repaint an accent-filled control ────────────
   53 selectors across the stylesheets pair an accent BACKGROUND with white
   TEXT: .btn-primary, .send-btn, every .active toolbar state, and the user's
   own message bubble. A theme that repaints their background does not repaint
   their text, so they end up white on white — invisible, not merely ugly. That
   is exactly what Neumorphism did to the preferences Save button, and to every
   message the user had sent.

   The fill is re-asserted here rather than each theme being made to avoid it,
   because "an accent control must stay legible" is a property of the app, not
   of any one theme — and the next theme to repaint a surface would rediscover
   this the same way.

   background-COLOR, not the background shorthand: Skeuomorphism layers a
   gradient through background-image, and the shorthand would silently erase
   it. This restores the fill and leaves the texture alone. */
html[data-style-theme]:not([data-style-theme="default"]) :is(
  .btn-primary, .btn-submit, .reg-submit, .send-btn, .send-btn-modern,
  .gw-btn-primary, .draw-sheet-done, .msg-user .msg-bubble,
  [class*="-btn"].active, [class*="-btn"].primary,
  [class*="-pill"].active, [class*="-tab"].active,
  /* NOT a bare .selected: .style-card.selected and .theme-card.selected are
     the theme pickers' own tiles, which use a soft tint and normal text. The
     guard would have turned them into solid primary blocks. Only the inner
     accent marks of a selected card qualify. */
  .payg-card.selected .payg-sel, .gw-card.selected .gw-check,
  /* Found by re-auditing every accent-filled selector against what a theme
     actually repaints, rather than by eye. These are the ones the first pass
     missed: chips that fill on hover, count badges, and the two icon buttons
     whose fill comes from an id rather than a class. */
  .active-agent-chip, .chip:hover, .followup-chip:hover, .citation-chip:hover,
  .gfc-btn.gen-file-download, .plan-pop-badge, .sc-count-badge,
  #mobile-new-chat-btn, #pwa-install-btn
) {
  background-color: var(--primary) !important;
  color: var(--on-accent, #fff) !important;
}

/* Avatars and numbered markers are accent-filled too, and are round by
   intent — a theme may square them, but must not blank them. */
html[data-style-theme]:not([data-style-theme="default"]) :is(
  .msg-avatar, .profile-avatar, .sf-avatar, .citation-num,
  .gw-step-num, .ld-step-num, .auth-logo-icon, .welcome-logo
) {
  background-color: var(--primary) !important;
  color: var(--on-accent, #fff) !important;
}

/* ── 8. EMPTY-SLOT GUARD — do not fill a border that is meant to be empty ──
   A number of components reserve a border and leave it TRANSPARENT, so that a
   later state can colour it without shifting the layout: .project-item keeps a
   2px left slot for the active accent, .tool-icon-btn and #mobile-new-chat-btn
   the same for hover, .composer-card for its draw/video/audio modes.

   Brutalism and Retroism set border-color across items, chips, bars and
   controls, which fills every one of those slots at once - so every project row
   wears the "selected" bar and every idle tool button looks pressed. The slot
   is a layout device, not a border anyone asked to see.

   Left transparent unless the element is actually in the state the slot exists
   for. The states themselves still colour it, because those rules are more
   specific than this one. */
html[data-style-theme="brutalism"] :is(.project-item, .tool-icon-btn, .composer-card):not(.active):not(.has-ref):not(.draw-mode):not(.video-mode):not(.audio-mode),
html[data-style-theme="retroism"]  :is(.project-item, .tool-icon-btn, .composer-card):not(.active):not(.has-ref):not(.draw-mode):not(.video-mode):not(.audio-mode) {
  border-left-color: transparent !important;
}
html[data-style-theme="brutalism"] :is(.tool-icon-btn, #mobile-new-chat-btn):not(:hover):not(.active),
html[data-style-theme="retroism"]  :is(.tool-icon-btn, #mobile-new-chat-btn):not(:hover):not(.active) {
  border-color: transparent !important;
}

/* ───────────────────────────────────────────────────────────────────────────
   1. MINIMALISM — nothing that is not carrying meaning
   Hairline borders, no elevation at all, gentle corners. The absence of shadow
   is the statement, so elevation goes to none rather than small.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="minimalism"] {
  --st-radius-sm: 3px;  --st-radius-md: 4px;  --st-radius-lg: 6px;
  --st-radius-pill: 999px;
  --st-elev-1: none;  --st-elev-2: none;  --st-elev-3: none;
  --st-border-width: 1px;
  --st-transition: all .16s ease;
}


/* ───────────────────────────────────────────────────────────────────────────
   2. MAXIMALISM — more of everything, unapologetically
   Deep elevation, generous rounding, heavy borders. Where Minimalism removes
   until only meaning is left, this keeps adding until the surface is full.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="maximalism"] {
  --st-radius-sm: 10px; --st-radius-md: 16px; --st-radius-lg: 24px;
  --st-radius-pill: 999px;
  --st-elev-1: 0 2px 8px hsl(var(--primary-h) 40% 30% / .18);
  --st-elev-2: 0 10px 30px hsl(var(--primary-h) 40% 30% / .24);
  --st-elev-3: 0 24px 60px hsl(var(--primary-h) 40% 30% / .30);
  --st-border-width: 2px;
  --st-transition: all .28s cubic-bezier(.34,1.56,.64,1);
}
/* The one place Maximalism earns an exception: a flat panel is not maximal.
   Tinted from the ACTIVE colour theme, so this stays colour-agnostic. */
html[data-style-theme="maximalism"] :is(
  [class*="-card"], [class="card"], [class*="-panel"], .modal-content,
  .acct-section, .msg-bubble, .reasoning-panel
) {
  background-image: linear-gradient(160deg,
    hsl(var(--primary-h) var(--primary-s) 50% / .06), transparent 60%);
}


/* ───────────────────────────────────────────────────────────────────────────
   3. BRUTALISM — the structure left showing
   Zero radius, thick borders, hard offset shadows with no blur, monospace.
   Nothing is softened and nothing pretends to be a physical object.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="brutalism"] {
  --st-radius-sm: 0; --st-radius-md: 0; --st-radius-lg: 0;
  --st-radius-pill: 0;          /* pills square off too — see the note above */
  --st-elev-1: 2px 2px 0 var(--text);
  --st-elev-2: 4px 4px 0 var(--text);
  --st-elev-3: 8px 8px 0 var(--text);
  --st-border-width: 2px;
  --st-font-stack: ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, Consolas, monospace;
  --st-transition: none;        /* nothing eases; things are where they are */
}
/* Offset shadows only work against a hard border, and --border is a soft tint
   in the default palette. Borrow --text, which is legible in every colour
   theme and both modes, rather than naming a colour of our own. */
html[data-style-theme="brutalism"] :is(
  [class*="-card"], [class="card"], [class*="-panel"], .modal-content,
  .acct-section, .msg-bubble, .reasoning-panel,
  button, [class*="-btn"], .btn,
  input:not([type="checkbox"]):not([type="radio"]), select, textarea,
  [class*="-item"], [class*="-chip"], .chip, [class*="-bar"], [class*="-strip"]
) {
  border-color: var(--text) !important;
}


/* ───────────────────────────────────────────────────────────────────────────
   4. MODERNISM — form follows function
   Restrained geometry, one modest elevation step, tight even corners. Close to
   the app's own look, which is the point: it is the classicist of the set.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="modernism"] {
  --st-radius-sm: 2px;  --st-radius-md: 4px;  --st-radius-lg: 8px;
  --st-radius-pill: 999px;
  --st-elev-1: none;
  --st-elev-2: 0 1px 2px rgba(0,0,0,.10);
  --st-elev-3: 0 4px 10px rgba(0,0,0,.12);
  --st-border-width: 1px;
  --st-transition: all .2s cubic-bezier(.4,0,.2,1);
}


/* ───────────────────────────────────────────────────────────────────────────
   5. POST-MODERNISM — the rules, quoted rather than obeyed
   Asymmetric corners, mixed weights, deliberate awkwardness. Every other theme
   here is internally consistent; this one is consistent about not being.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="post-modernism"] {
  --st-radius-sm: 2px 8px 2px 8px;
  --st-radius-md: 4px 14px 4px 14px;
  --st-radius-lg: 6px 22px 6px 22px;
  --st-radius-pill: 999px 4px 999px 4px;
  --st-elev-1: 1px 2px 0 hsl(var(--primary-h) 60% 60% / .5);
  --st-elev-2: 3px 5px 0 hsl(var(--primary-h) 60% 60% / .4);
  --st-elev-3: 6px 9px 0 hsl(var(--primary-h) 60% 60% / .3);
  --st-border-width: 2px;
  --st-transition: all .22s cubic-bezier(.68,-.55,.27,1.55);
}
/* Mirror the asymmetry on the user's own messages so the two sides of the
   conversation are visibly not the same shape — the whole idea in one detail. */
html[data-style-theme="post-modernism"] .msg-user .msg-bubble {
  border-radius: 22px 6px 22px 6px !important;
}


/* ───────────────────────────────────────────────────────────────────────────
   6. SKEUOMORPHISM — pretending to be an object
   Bevels, gradients and inner highlights: light from above, a lip at the top
   edge, a shadow underneath. Needs its own rules because a bevel is a stack of
   insets, which no single token can express.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="skeuomorphism"] {
  --st-radius-sm: 5px;  --st-radius-md: 8px;  --st-radius-lg: 12px;
  --st-radius-pill: 999px;
  --st-elev-1: 0 1px 0 rgba(255,255,255,.55) inset, 0 1px 2px rgba(0,0,0,.20);
  --st-elev-2: 0 1px 0 rgba(255,255,255,.55) inset, 0 2px 5px rgba(0,0,0,.22);
  --st-elev-3: 0 1px 0 rgba(255,255,255,.55) inset, 0 6px 16px rgba(0,0,0,.28);
  --st-border-width: 1px;
  --st-transition: all .18s ease-out;
}
html[data-style-theme="skeuomorphism"] :is(
  button, [class*="-btn"], .btn,
  input:not([type="checkbox"]):not([type="radio"]), select, textarea, [class*="-chip"], .chip, [class*="-pill"]
) {
  background-image: linear-gradient(180deg, rgba(255,255,255,.22), rgba(0,0,0,.06));
}
/* A pressed control moves the light source: the top highlight becomes a top
   shadow. That reversal is what makes it read as a physical button. */
html[data-style-theme="skeuomorphism"] :is(button, [class*="-btn"], .btn):active {
  box-shadow: 0 2px 4px rgba(0,0,0,.25) inset !important;
  background-image: linear-gradient(180deg, rgba(0,0,0,.08), rgba(255,255,255,.10));
}


/* ───────────────────────────────────────────────────────────────────────────
   7. NEUMORPHISM — extruded from the background
   Paired shadows, light from the top-left and dark from the bottom-right, on a
   surface the same tone as what is behind it. Borders are removed entirely:
   the form comes only from the light.

   KNOWN TRADE: this is low-contrast by definition. It is offered as a choice,
   not recommended, and it is the one theme here that will not satisfy WCAG
   contrast on its edges. Text contrast is untouched.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="neumorphism"] {
  --st-radius-sm: 8px;  --st-radius-md: 14px; --st-radius-lg: 22px;
  --st-radius-pill: 999px;
  --st-elev-1: 3px 3px 7px rgba(0,0,0,.13), -3px -3px 7px rgba(255,255,255,.65);
  --st-elev-2: 6px 6px 14px rgba(0,0,0,.13), -6px -6px 14px rgba(255,255,255,.70);
  --st-elev-3: 10px 10px 24px rgba(0,0,0,.15), -10px -10px 24px rgba(255,255,255,.70);
  --st-border-width: 0;
  --st-transition: all .2s ease;
}
/* Surface and background must match or the extrusion illusion collapses. */
html[data-style-theme="neumorphism"] :is(
  [class*="-card"], [class="card"], [class*="-panel"], .modal-content,
  .acct-section, .msg-bubble, .reasoning-panel,
  button, [class*="-btn"], .btn,
  input:not([type="checkbox"]):not([type="radio"]), select, textarea,
  [class*="-item"], [class*="-chip"], .chip, [class*="-pill"], [class*="-badge"]
) {
  background: var(--bg) !important;
  border: 0 !important;
}
/* Pressed = pushed in. Same two shadows, moved inside. */
/* Rows lose their hover feedback for the same reason they lost their active
   tint: the repaint above carries !important, so .session-item:hover's own
   background cannot win. A sidebar where nothing responds to the pointer reads
   as broken, so hover is given back as a raised edge - the neumorphic way of
   saying "this is live" without introducing a colour the theme does not use. */
html[data-style-theme="neumorphism"] :is(
  .session-item, .project-item, .folder-item, [class*="-nav-link"]
):hover {
  box-shadow: 2px 2px 5px rgba(0,0,0,.10),
             -2px -2px 5px rgba(255,255,255,.55) !important;
}

/* Items are repainted to --bg above, which also erases the active row's own
   tint - so an active project or session became indistinguishable from an
   inactive one. Pressed-in shadows say "selected" in this language. */
html[data-style-theme="neumorphism"] :is(.project-item, .session-item, .folder-item).active {
  box-shadow: 2px 2px 5px rgba(0,0,0,.13) inset,
             -2px -2px 5px rgba(255,255,255,.60) inset !important;
}

html[data-style-theme="neumorphism"] :is(button, [class*="-btn"], .btn, [class*="-item"]):active {
  box-shadow: 3px 3px 7px rgba(0,0,0,.15) inset,
             -3px -3px 7px rgba(255,255,255,.60) inset !important;
}
/* Dark and OLED have no white to catch, so the light half is dropped to a faint
   grey. Without this the theme simply disappears in dark mode. */
html[data-style-theme="neumorphism"]:is([data-theme="dark"], [data-theme="oled"]) {
  --st-elev-1: 3px 3px 7px rgba(0,0,0,.55), -3px -3px 7px rgba(255,255,255,.04);
  --st-elev-2: 6px 6px 14px rgba(0,0,0,.55), -6px -6px 14px rgba(255,255,255,.05);
  --st-elev-3: 10px 10px 24px rgba(0,0,0,.60), -10px -10px 24px rgba(255,255,255,.05);
}


/* ───────────────────────────────────────────────────────────────────────────
   8. GLASSMORPHISM — frosted panes over the background
   Translucent surfaces with a blur behind them and a bright hairline edge.

   PERFORMANCE: backdrop-filter is expensive, and this codebase has already had
   to remove it from .mobile-topbar because it left a stuck blurred layer on
   mobile Safari during transforms. So the blur is dropped below 768px and
   under reduced-motion, leaving plain translucency — the look survives, the
   scrolling does too.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="glassmorphism"] {
  --st-radius-sm: 8px;  --st-radius-md: 12px; --st-radius-lg: 18px;
  --st-radius-pill: 999px;
  --st-elev-1: 0 2px 8px rgba(0,0,0,.10);
  --st-elev-2: 0 8px 32px rgba(0,0,0,.14);
  --st-elev-3: 0 16px 48px rgba(0,0,0,.18);
  --st-border-width: 1px;
  --st-transition: all .24s ease;
}
html[data-style-theme="glassmorphism"] :is(
  [class*="-card"], [class="card"], [class*="-panel"], .modal-content,
  .acct-section, .msg-bubble, .reasoning-panel,
  .app-sidebar, [class*="-menu"], [class*="popover"]
) {
  background: color-mix(in srgb, var(--surface) 62%, transparent) !important;
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  border-color: color-mix(in srgb, var(--text) 12%, transparent) !important;
}
/* The app marks the active project and session rows with a 2px primary rule
   down the left edge (.project-item.active { border-left-color: var(--primary) }).
   That is the right device against solid surfaces, and Brutalism and Retroism
   want it emphatically - but against a frosted, borderless pane it reads as a
   stray line rather than an accent, because nothing else here has a hard opaque
   edge. Glass states its own selection through the surface, so the row keeps
   its background and loses the rule. Flat, Material and Neumorphism already
   drop it as a side effect of being borderless. */
html[data-style-theme="glassmorphism"] :is(
  .project-item, .session-item, [class*="-item"]
) {
  border-left-color: transparent !important;
}
html[data-style-theme="glassmorphism"] :is(.project-item, .session-item).active {
  background: color-mix(in srgb, var(--primary) 14%, transparent) !important;
}
/* The composer textarea is not a control in its own right: .composer-card is
   the thing you see and click, and #chat-input is a transparent, borderless
   field sitting inside it. Group 3 above matches every textarea, so glass was
   handing the field its own radius, its own elevation and an all-property
   .24s transition - which is why focusing it visibly re-shaped the composer on
   desktop. The card already carries the frosted surface and states focus via
   :focus-within, so the field inside it is left exactly as the app draws it. */
html[data-style-theme="glassmorphism"] #chat-input {
  border-radius: 0 !important;
  box-shadow: none !important;
  background: transparent !important;
  transition: none !important;
}

@media (max-width: 768px), (prefers-reduced-motion: reduce) {
  html[data-style-theme="glassmorphism"] :is(
    [class*="-card"], [class="card"], [class*="-panel"], .modal-content,
    .acct-section, .msg-bubble, .reasoning-panel,
    .app-sidebar, [class*="-menu"], [class*="popover"]
  ) {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: color-mix(in srgb, var(--surface) 92%, transparent) !important;
  }
}


/* ───────────────────────────────────────────────────────────────────────────
   9. MATERIAL DESIGN — paper at measured heights
   Google's elevation ramp: a small fixed radius and shadows that say how far
   off the page a surface is, rather than how pretty it looks.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="material"] {
  --st-radius-sm: 4px;  --st-radius-md: 4px;  --st-radius-lg: 8px;
  --st-radius-pill: 999px;
  --st-elev-1: 0 1px 3px rgba(0,0,0,.20), 0 1px 1px rgba(0,0,0,.14);
  --st-elev-2: 0 3px 6px rgba(0,0,0,.16), 0 3px 6px rgba(0,0,0,.23);
  --st-elev-3: 0 10px 20px rgba(0,0,0,.19), 0 6px 6px rgba(0,0,0,.23);
  --st-border-width: 0;
  --st-transition: all .2s cubic-bezier(.4,0,.2,1);
}
/* Elevation rises on interaction — the sheet lifts toward the finger. */
html[data-style-theme="material"] :is(button, [class*="-btn"], .btn):hover {
  box-shadow: var(--st-elev-2) !important;
}
html[data-style-theme="material"] :is(
  [class*="-card"], [class="card"], [class*="-panel"], .modal-content,
  .acct-section, .msg-bubble, .reasoning-panel, [class*="-item"], [class*="-chip"], .chip
) {
  border: 0 !important;
}


/* ───────────────────────────────────────────────────────────────────────────
   10. FLAT DESIGN — colour and edge, nothing else
   No shadow anywhere, no border, small corners. Distinct from Minimalism,
   which keeps its hairline borders; Flat drops them and leans on fill alone.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="flat"] {
  --st-radius-sm: 2px;  --st-radius-md: 3px;  --st-radius-lg: 4px;
  --st-radius-pill: 999px;
  --st-elev-1: none;  --st-elev-2: none;  --st-elev-3: none;
  --st-border-width: 0;
  --st-transition: all .15s linear;
}
html[data-style-theme="flat"] :is(
  [class*="-card"], [class="card"], [class*="-panel"], .modal-content,
  .acct-section, .msg-bubble, .reasoning-panel,
  button, [class*="-btn"], .btn,
  input:not([type="checkbox"]):not([type="radio"]), select, textarea,
  [class*="-item"], [class*="-chip"], .chip, [class*="-pill"], [class*="-badge"],
  [class*="-bar"], [class*="-strip"]
) {
  border: 0 !important;
}


/* ───────────────────────────────────────────────────────────────────────────
   11. RETROISM — a terminal, roughly
   Square corners, hard edges, a glowing offset in the active colour, and a
   monospace face. The glow is built from --primary so it retunes itself to
   whichever colour theme is on rather than hardcoding a CRT green.
   ─────────────────────────────────────────────────────────────────────────── */
html[data-style-theme="retroism"] {
  --st-radius-sm: 0; --st-radius-md: 0; --st-radius-lg: 2px;
  --st-radius-pill: 0;
  --st-elev-1: 0 0 0 1px hsl(var(--primary-h) var(--primary-s) 50% / .35);
  --st-elev-2: 3px 3px 0 hsl(var(--primary-h) var(--primary-s) 50% / .45);
  --st-elev-3: 0 0 18px hsl(var(--primary-h) var(--primary-s) 55% / .40);
  --st-border-width: 1px;
  --st-font-stack: ui-monospace, 'Courier New', Courier, monospace;
  --st-transition: none;
}
html[data-style-theme="retroism"] :is(
  [class*="-card"], [class="card"], [class*="-panel"], .modal-content,
  .acct-section, .msg-bubble, .reasoning-panel,
  button, [class*="-btn"], .btn,
  input:not([type="checkbox"]):not([type="radio"]), select, textarea,
  [class*="-item"], [class*="-bar"], [class*="-strip"]
) {
  border-color: hsl(var(--primary-h) var(--primary-s) 50% / .55) !important;
}
/* Scanlines, at a weight you notice only if you look for them. Fixed and
   pointer-events:none so it never intercepts a click or scrolls out of step.
   Dropped under reduced-motion: a static overlay is still visual noise, and
   this is exactly the kind someone enabling that setting is asking to avoid. */
@media (prefers-reduced-motion: no-preference) {
  html[data-style-theme="retroism"] body::after {
    content: "";
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 9999;
    background: repeating-linear-gradient(
      180deg, rgba(0,0,0,.045) 0 1px, transparent 1px 3px);
  }
}


/* ───────────────────────────────────────────────────────────────────────────
   THE PICKER (account.php)
   Layout for the option list, plus the swatches. Each swatch is rendered by
   the theme it is offering rather than by a hand-drawn approximation, so a
   tile cannot drift out of step with what choosing it actually does. That is
   why these rules live here and not in settings.css: they have to sit beside
   the theme definitions to stay honest.
   ─────────────────────────────────────────────────────────────────────────── */
.style-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 10px;
}
.style-card {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  text-align: left;
  padding: 12px 13px;
  border: 1.5px solid var(--border);
  border-radius: 11px;
  background: var(--surface);
  cursor: pointer;
  position: relative;
  transition: border-color .15s ease, background .15s ease;
}
.style-card:hover  { border-color: var(--primary); }
.style-card.selected { border-color: var(--primary); background: var(--accent-softer); }
.sc-swatch { flex: 0 0 auto; width: 34px; height: 34px; margin-top: 1px; }
.sc-body   { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sc-name   { font-size: .85rem; font-weight: 700; }
.sc-desc   { font-size: .73rem; color: var(--muted); line-height: 1.45; }
.sc-note   { font-size: .69rem; color: var(--muted); opacity: .85; font-style: italic; margin-top: 2px; }
.sc-check  { position: absolute; top: 9px; right: 10px; font-size: .8rem;
             color: var(--primary); opacity: 0; transition: opacity .15s ease; }
.style-card.selected .sc-check { opacity: 1; }

/* Swatches. Same shape language each theme applies to a real surface, at 34px.
   Colour comes from the active colour theme, exactly as the themes themselves
   do, so a swatch shown in Claude orange previews Claude orange. */
.sc-swatch { background: var(--accent-200); border: 1px solid var(--border); }
[data-style-preview="default"]        { border-radius: 10px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
[data-style-preview="minimalism"]     { border-radius: 4px;  box-shadow: none; }
[data-style-preview="maximalism"]     { border-radius: 14px; box-shadow: 0 4px 12px rgba(0,0,0,.28); border-width: 2px; }
[data-style-preview="brutalism"]      { border-radius: 0; box-shadow: 3px 3px 0 var(--text); border: 2px solid var(--text); }
[data-style-preview="modernism"]      { border-radius: 3px;  box-shadow: 0 1px 2px rgba(0,0,0,.14); }
[data-style-preview="post-modernism"] { border-radius: 3px 14px 3px 14px; box-shadow: 3px 4px 0 hsl(var(--primary-h) 60% 60% / .5); border-width: 2px; }
[data-style-preview="skeuomorphism"]  { border-radius: 8px;
  background-image: linear-gradient(180deg, rgba(255,255,255,.5), rgba(0,0,0,.12));
  box-shadow: 0 1px 0 rgba(255,255,255,.6) inset, 0 2px 4px rgba(0,0,0,.25); }
[data-style-preview="neumorphism"]    { border-radius: 12px; border: 0; background: var(--bg);
  box-shadow: 3px 3px 6px rgba(0,0,0,.16), -3px -3px 6px rgba(255,255,255,.7); }
[data-style-preview="glassmorphism"]  { border-radius: 11px;
  background: color-mix(in srgb, var(--accent-300) 55%, transparent);
  backdrop-filter: blur(4px); box-shadow: 0 4px 14px rgba(0,0,0,.14);
  border-color: color-mix(in srgb, var(--text) 14%, transparent); }
[data-style-preview="material"]       { border-radius: 4px; border: 0;
  box-shadow: 0 3px 6px rgba(0,0,0,.18), 0 3px 6px rgba(0,0,0,.22); }
[data-style-preview="flat"]           { border-radius: 2px; border: 0; box-shadow: none;
  background: var(--accent-400); }
[data-style-preview="retroism"]       { border-radius: 0;
  border-color: hsl(var(--primary-h) var(--primary-s) 50% / .6);
  box-shadow: 3px 3px 0 hsl(var(--primary-h) var(--primary-s) 50% / .45); }

/* Dark mode: the neumorphic swatch has no white to catch, same as the theme. */
[data-theme="dark"]  [data-style-preview="neumorphism"],
[data-theme="oled"]  [data-style-preview="neumorphism"] {
  box-shadow: 3px 3px 6px rgba(0,0,0,.6), -3px -3px 6px rgba(255,255,255,.05);
}
