/* =========================================================================
   PUBLIC COMMERCIAL SURFACE, the VinDevs brand, from the brand book
   =========================================================================
   Source of truth: VinDevs-xyz brand book.
     Deep teal  #182B30 / #164346 , technology, trust, professionalism
     Brick red  #7B241E / #9E291E , energy, ambition; the crown and ".xyz"
     Warm gray  #D8D7D2           , the neutral
     White canvas; "Vin" bold + "Devs" light; Innovate. Build. Inspire.

   The commercial surface reads like a modern services marketplace (white,
   search-led, comparable cards) wearing THESE colours, not the electric
   blue of the internal Developer OS, which appears nowhere in the book.

   Scope: everything here lives under html:is([data-surface="public"], [data-color-mode="light"]), stamped by
   renderPage on commercial routes. The OS keeps its own identity elsewhere.
   This file loads LAST in the shell cascade and wins by order + scope,
   no !important war.

   This is the ONE place raw brand values may appear; everything else
   consumes the tokens.
   ========================================================================= */

html:is([data-surface="public"], [data-color-mode="light"]) {
    /* ---- Brand palette -------------------------------------------------- */
    --brand-ink: #182b30; /* deep teal-black: headings, primary text */
    --brand-teal: #164346; /* primary action */
    --brand-teal-deep: #0f3134; /* action hover */
    --brand-teal-soft: #eef4f3; /* tinted fills, selected states */
    --brand-red: #9e291e; /* energy accent: crown, eyebrows, details */
    --brand-red-deep: #7b241e;
    --brand-gray: #d8d7d2; /* the neutral: borders, dividers */
    /* The canvas was #fafaf9, luminance 0.968, against cards at 1.000.
       Measured across 146 pages in light mode, 99.7% of every painted surface
       computed to pure #ffffff: page, shell, rails and cards were all the same
       value, so nothing read as raised, nothing read as recessed, and the whole
       viewport sat at maximum brightness. That is the eye strain, not the
       contrast of any one element, but a field with no darker value anywhere in
       it. Dropping the field to 0.877 costs nothing in legibility (ink still
       clears 12.6:1 on it) and gives white cards something to sit ON, which is
       what makes a light UI readable rather than merely bright. */
    --brand-canvas: #f2f1ed; /* warm light field, the page itself */
    --brand-surface: #ffffff; /* cards and panels: bounded, never full-bleed */
    --brand-sunken: #e7e6e0; /* wells, tracks, code blocks, empty states */

    /* ---- Canonical scales (manifesto) -----------------------------------
       Now aliases of the shared --type-* scale in design-system.css (same
       values, promoted so the dark surface reads the same vocabulary).
       Existing --pub-* callers keep working; the values live in one place. */
    --pub-type-caption: var(--type-caption);
    --pub-type-small: var(--type-small);
    --pub-type-body: var(--type-body);
    --pub-type-lede: var(--type-lede);
    --pub-type-h3: var(--type-h3);
    --pub-type-h2: var(--type-h2);
    /* Spec §24: commercial hero caps at 56px desktop. */
    --pub-type-hero: var(--type-hero);

    /* The premium tier signal is tuned for the dark canvas; on warm
       near-white it falls to ~2.4:1 and stops reading as a colour at all.
       Light mode re-points the token to the brand's own energy accent, so
       "paid tier" stays legible without importing a colour the brand book
       does not contain. */
    --premium-gold: var(--brand-red);
    --premium-gold-rgb: 158, 41, 30;

    /* The brand mark is a fixed near-white asset drawn for dark headers; light
       surfaces swap in the ink variant (same paths, #182B30). */
    --brand-mark-url: url("/assets/brand/mark-dark.svg");

    /* The shared top bar reads these; on the light surface they must resolve
       to ink, not the OS near-white (the invisible-wordmark bug). */
    --vd-top-bg: rgba(255, 255, 255, 0.92);
    --vd-top-border: var(--brand-gray);
    --vd-top-ink: #45585c;
    --vd-top-ink-strong: #182b30;
    /* The rest of the nav token set, re-pointed for light. The dark values
       (a near-white ink and a light-blue accent) are invisible on paper, so
       the focus ring and the selected indicator both need ink-side values.
       The accent is the brand's own teal (10.9:1 on white), not a second
       blue, the structure is shared with dark mode, only the hue differs. */
    --vd-top-panel: var(--brand-surface);
    --vd-top-panel-raised: var(--brand-canvas);
    --vd-top-border-strong: var(--brand-ink-20, rgba(24, 43, 48, 0.28));
    --vd-top-ink-muted: #5e6f72;
    --vd-top-hover: rgba(24, 43, 48, 0.06);
    --vd-top-selected: rgba(24, 43, 48, 0.1);
    --vd-top-accent: var(--brand-teal);
    /* TWO radii, not four. 8 / 10 / 12 were all live at once and 2px apart,
       nobody can see the difference between a 10px card and a 12px one, but
       every author has to guess which to reach for, which is how a page ends
       up with three of them side by side. Controls are 8, every surface is 12.
       --pub-radius-md is kept as an alias so existing callers land on 12.
       The pill is RESERVED for interactive filter chips (the popular-search
       terms); a static label is not a pill. */
    --pub-radius-sm: 8px;
    --pub-radius-md: 12px;
    --pub-radius-lg: 12px;
    --pub-radius-pill: 999px;

    /* The shell's own scale (8/12/16/20) has to COLLAPSE onto the one above,
       not run beside it. Without this the commercial surface renders two
       radius systems at once: anything reading --ds-radius-lg sits at 16px
       next to a --pub-radius-lg surface at 12px, and --ds-radius-xl adds a
       20px step the brand scale does not have. Measured on the published
       portfolio before this: 8 / 12 / 16 / 20 / 999 / 50% on one page. */
    /* A THIRD body size: render.css sets --text-size-base to 0.98rem and
       .panel p / .section-block p (0,1,1) consume it, which quietly outranks
       any single-class component rule. That is why the portfolio tagline,
       CTA copy and review note rendered at 15.68px while their own stylesheet
       asked for 16px. One body size on this surface. */
    --text-size-base: var(--type-body);
    /* Same story one step down: --text-size-sm is 0.9rem / a 0.88–0.98rem
       clamp depending on which block wins, i.e. 14.4–15.7px where the scale
       says 14. .subtle and friends consume it. */
    --text-size-sm: var(--type-small);

    --ds-radius-sm: var(--pub-radius-sm);
    --ds-radius-md: var(--pub-radius-md);
    --ds-radius-lg: var(--pub-radius-lg);
    --ds-radius-xl: var(--pub-radius-lg);

    /* ---- One spatial system ---------------------------------------------
       A visitor walks / → /services → /work → /portfolios → /marketplace in
       one session. Those five pages were rendering at 1180 / 1280 / 1280 /
       1320 / 1440px, so the content edge jumped on every click and no two
       pages shared a vertical line. Density may differ between a marketing
       page and a dense grid (that is allowed); the content WIDTH may not. */
    --pub-container: var(--container-max);
    --pub-gutter: var(--space-32);

    /* ---- One motion language --------------------------------------------
       Measured across the public pages: 150 / 160 / 170 / 180 / 190 / 200 /
       220 / 240 / 320 / 340 / 380ms, eleven durations, i.e. a different
       animation personality per stylesheet. Three steps, ease-out, no bounce. */
    --pub-duration-fast: 120ms;
    --pub-duration-base: 180ms;
    --pub-duration-slow: 260ms;
    --pub-ease: cubic-bezier(0.2, 0, 0, 1);

    /* ---- Elevation on a light canvas -------------------------------------
       The OS shadow tokens are tuned for a near-black canvas (oklch(0.06 …)
       and rgba(6,10,22,…)); on #fafaf9 they read as dirty smudges. Three
       levels, and level 0, no shadow at all, is the default for content. */
    --pub-elev-1: 0 1px 2px rgba(24, 43, 48, 0.06);
    --pub-elev-2: 0 4px 12px rgba(24, 43, 48, 0.08);
    --pub-elev-3: 0 16px 40px rgba(24, 43, 48, 0.14);
    /* Re-point the shared elevation ladder (design-system.css) at the light
       canvas, so a component asking for --elev-2 gets a shadow tuned for the
       surface it is actually sitting on instead of a dark-canvas one. */
    --elev-1: var(--pub-elev-1);
    --elev-2: var(--pub-elev-2);
    --elev-3: var(--pub-elev-3);

    /* ---- Repoint the shell token layer at the brand --------------------- */
    --ds-canvas: var(--brand-canvas);
    --ds-canvas-raised: var(--brand-sunken);
    --ds-surface: var(--brand-surface);
    --ds-surface-hover: #f4f5f3;
    --ds-surface-selected: var(--brand-teal-soft);
    --ds-border: #dedcd5;
    --ds-border-strong: #bfbdb4;
    --ds-text: var(--brand-ink);
    --ds-text-muted: #4d6165;
    /* Was #66777a, 4.48:1 on --brand-canvas, a WCAG AA fail at every size
       this token is actually used at: the hero trust line (13.8px), the
       "Popular:" label, the network metric captions. Two steps darker clears
       it. On the retuned canvas it measures 4.6:1, still AA, and nothing on a
       light surface may sit subtler than this. */
    --ds-text-subtle: #57696d;

    /* Body copy is NOT --ds-text. Ink on the canvas is 12.6:1; a whole
       paragraph set at maximum contrast is the other half of the eye-strain
       complaint, and it also leaves headings nothing to be darker than. Body
       lands at 9.3:1, comfortably AA, visibly quieter than a heading. */
    --ds-text-body: #2e4247;
    /* Links need to be a colour, not just underlined ink. The action teal is
       #164346 (10.9:1 on white) which reads as body copy at a glance; one step
       up the same hue keeps 7.5:1 and actually looks clickable. */
    --ds-link: #0f5f63;
    --ds-link-hover: var(--brand-teal-deep);

    --ds-accent: var(--brand-teal);
    --ds-accent-hover: var(--brand-teal-deep);
    --ds-accent-ink: #ffffff;
    /* Deep teal is already dark enough to carry white ink, so the fill and the
       accent are the same value here, the token still exists so components
       ask for the right role rather than guessing. */
    --ds-accent-solid: var(--brand-teal);
    /* The OS ring is the accent lifted toward white so it shows on near-black.
       Run that here and the ring lands on a near-white canvas at ~1.4:1, i.e.
       invisible. On this surface the ring goes the other way: the darkest step
       of the brand teal, 12.3:1 on the canvas, 13.9:1 on a white card. */
    --focus-ring: var(--brand-teal-deep);
    /* Light canvas: status text is darkened, not lightened. */
    --status-ink-mix: black;
    /* #1e7a4f measured 4.37:1 as 12px badge text on its own tint, under the
       AA floor. Two steps darker clears it at 5.3:1 there and 6.5:1 on white. */
    --ds-success: #1a6b45;
    --ds-warning: #8a5f10;
    --ds-danger: #b03a2e;

    /* Legacy alias layer so older rules resolve to the brand too. */
    --bg-surface: #ffffff;
    --bg-glass: #ffffff;
    --border-soft: rgba(24, 43, 48, 0.14);
    --border-strong: rgba(24, 43, 48, 0.26);
    --glass-border: rgba(24, 43, 48, 0.16);
    --text-strong: var(--brand-ink);
    --text-primary: var(--ds-text-body);
    --text-muted: #4d6165;
    --text-subtle: #57696d;
    --accent-primary: var(--brand-teal);
    --accent-secondary: #45585c;
    --accent-warning: #8a5f10;
    --accent-danger: #b03a2e;

    color-scheme: light;
    background: var(--brand-canvas);
}

/* ---- Canvas: flat and calm -------------------------------------------- */
html:is([data-surface="public"], [data-color-mode="light"]) body,
html:is([data-surface="public"], [data-color-mode="light"]) :is(body, :root)[data-hype-theme="simplistic"] {
    background: var(--brand-canvas);
    color: var(--brand-ink);
}
/* dev-os.css re-stamps the dark OS aliases at body level; the light surface
   must win there too, or any component reading these tokens renders as a
   dark tile on the light canvas (the pf-card leak). Same token set as the
   html-level block above, at body specificity, loaded last. */
html:is([data-surface="public"], [data-color-mode="light"]) body {
    --bg-surface: #ffffff;
    --bg-glass: #ffffff;
    --bg-panel: #ffffff;
    --border-soft: rgba(24, 43, 48, 0.14);
    --border-strong: rgba(24, 43, 48, 0.26);
    --glass-border: rgba(24, 43, 48, 0.16);
    --text-strong: var(--brand-ink);
    --text-primary: var(--ds-text-body);
    --text-muted: #4d6165;
    --text-subtle: #57696d;
    --accent: var(--brand-teal);
    --accent-primary: var(--brand-teal);
    --accent-secondary: #4d6165;
    --accent-warning: #8a5f10;
    --accent-danger: #b03a2e;
    --ds-canvas: var(--brand-canvas);
    --ds-canvas-raised: var(--brand-sunken);
    --ds-surface: var(--brand-surface);
    --ds-surface-hover: #f4f5f3;
    --ds-surface-selected: var(--brand-teal-soft);
    --ds-border: #dedcd5;
    --ds-border-strong: #bfbdb4;
    --ds-text: var(--brand-ink);
    --ds-text-muted: #4d6165;
    --ds-text-subtle: #57696d;
    --ds-text-body: #2e4247;
    --ds-link: #0f5f63;
    --ds-link-hover: var(--brand-teal-deep);
    --ds-accent: var(--brand-teal);
    --ds-accent-hover: var(--brand-teal-deep);
    --ds-accent-ink: #ffffff;
    --shadow-soft: 0 1px 0 rgba(24, 43, 48, 0.02), 0 8px 20px rgba(24, 43, 48, 0.07);
    --shadow-strong: 0 1px 0 rgba(24, 43, 48, 0.03), 0 18px 44px rgba(24, 43, 48, 0.12);
    --button-primary-start: var(--brand-teal);
    --button-primary-end: var(--brand-teal-deep);
    --button-primary-ink: #ffffff;
    --button-primary-border: rgba(22, 67, 70, 0.4);
    --button-primary-shadow: 0 8px 20px rgba(22, 67, 70, 0.18);
    --button-primary-shadow-hover: 0 10px 24px rgba(22, 67, 70, 0.24);
    /* dev-os.css re-stamps the OS ring at body level, so the light ring has to
       be re-stamped here too, same value as the html-level block above. */
    --focus-ring: var(--brand-teal-deep);
    --button-focus-ring: var(--focus-ring);
    --button-secondary-bg-a: #ffffff;
    --button-secondary-bg-b: #ffffff;
    --button-secondary-border: rgba(24, 43, 48, 0.22);
    --button-secondary-shadow: 0 4px 12px rgba(24, 43, 48, 0.08);
    --nav-surface: rgba(255, 255, 255, 0.92);
    --nav-blur: rgba(255, 255, 255, 0.86);
    --nav-border: var(--brand-gray);
    --glow-a: transparent;
    --glow-b: transparent;
    --workspace-top-glow: transparent;
}
html:is([data-surface="public"], [data-color-mode="light"]) body::before,
html:is([data-surface="public"], [data-color-mode="light"]) body::after {
    content: none;
}

/* ---- Top bar: white, bordered, quiet ----------------------------------- */
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top {
    background: rgba(255, 255, 255, 0.92);
    border-bottom: 1px solid var(--brand-gray);
    backdrop-filter: saturate(1.2) blur(8px);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__link {
    color: #45585c;
    border-radius: var(--pub-radius-sm);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__link:hover,
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__link:focus-visible {
    color: var(--brand-ink);
    background: #f2f4f3;
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__link.is-active,
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__link[aria-current="page"] {
    color: var(--brand-ink);
    background: var(--brand-teal-soft);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__surface {
    color: #5e6f72;
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__burger {
    background: #ffffff;
    border: 1px solid var(--brand-gray);
    color: var(--brand-ink);
}
/* Mobile drawer follows the light surface. */
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer {
    background: var(--brand-canvas);
    border-color: var(--brand-gray);
    box-shadow: -28px 0 80px rgba(24, 43, 48, 0.18);
}
/* Matches the dark drawer: rows are list items, not one card each. */
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer .vd-top__link {
    background: transparent;
    border: 0;
    color: #45585c;
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer .vd-top__link:hover {
    background: var(--vd-top-hover);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer .vd-top__link.is-active {
    background: var(--brand-teal-soft);
    color: var(--brand-ink);
    box-shadow: inset 2px 0 0 var(--vd-top-accent);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer-head span,
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer-current span {
    color: #5e6f72;
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer-head strong,
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer-current strong {
    color: var(--brand-ink);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer-current {
    background: var(--brand-surface);
    border: 1px solid var(--brand-gray);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__drawer-close {
    background: var(--brand-surface);
    border: 1px solid var(--brand-gray);
    color: var(--brand-ink);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-top__scrim {
    background: rgba(24, 43, 48, 0.32);
}
/* Focus mode is an OS-only control and has no business on the commercial
   surface. Public-only on purpose: signed-in light mode keeps it.

   The colour-mode toggle used to be hidden here too, and that was the last of
   three locks that left signed-out visitors, everyone without an account yet
  , stuck in light with no way out. (The other two: renderPage omitted the
   colour-mode bootstrap on this surface, and runtime.js returned before
   binding the toggle's click listener.) The commercial look is this surface's
   DEFAULT colour mode now, not a cage, so the control that leaves it has to be
   reachable. */
html[data-surface="public"] [data-focus-mode-toggle] {
    display: none;
}

/* ---- Type -------------------------------------------------------------- */
html[data-surface="public"] body {
    font-size: var(--pub-type-body);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}
html[data-surface="public"] main :is(h1, .hero h1) {
    font-size: var(--pub-type-hero);
    line-height: 1.06;
    letter-spacing: -0.02em;
    font-weight: 700;
    color: var(--brand-ink);
    text-wrap: balance;
}
html[data-surface="public"] main h2 {
    /* The preferred term used to be 1.3rem + 1.1vw, which only reaches the
       2.25rem ceiling at a ~1382px viewport, so the most common desktop width
       (1280) rendered every H2 at 34.88px and the declared scale step was
       unreachable in practice. This lands exactly on 36px from 1250px up. */
    font-size: clamp(1.625rem, 1rem + 1.6vw, var(--pub-type-h2));
    line-height: 1.15;
    letter-spacing: -0.01em;
    font-weight: 700;
    color: var(--brand-ink);
}
html[data-surface="public"] main h3 {
    font-size: var(--pub-type-h3);
    line-height: 1.25;
    font-weight: 600;
    color: var(--brand-ink);
}
html[data-surface="public"] main p {
    color: #45585c;
}

/* ---- Hero: open, on the canvas ----------------------------------------- */
html:is([data-surface="public"], [data-color-mode="light"]) :is(.hero, .hero-surface, .vt-hero) {
    background: transparent;
    background-image: none;
    border: 0;
    box-shadow: none;
    backdrop-filter: none;
}
/* Brand moment: the eyebrow is the brick-red energy accent, the ".xyz". */
html:is([data-surface="public"], [data-color-mode="light"]) .hero-eyebrow {
    background: transparent;
    border: 0;
    padding-left: 0;
    color: var(--brand-red);
    letter-spacing: 0.16em;
    font-weight: 700;
}

/* ---- One content column across every public page ----------------------- */
/* Deliberately outspecifies the per-page overrides that set 1180 / 1320 /
   1440px (render.ts's .home-container, design-system.css's
   body[data-page^="marketplace"], discovery-hub.css's marketplace block).
   Those files load after this one, so this needs html+body+main to win,
   which is also the honest signal that they were competing in the first
   place. Fix the page rules and this can go back to a single class. */
html[data-surface="public"] body main > .container {
    max-width: var(--pub-container);
    padding-inline: var(--pub-gutter);
}

/* ---- One page title, one size ------------------------------------------ */
/* The page H1 measured 56 / 56.32 / 43.2px across /, /services, /work,
   /marketplace and /portfolios, three sizes for the same document role,
   because each page stylesheet invented its own hero clamp. The ramp is
   declared once, at the top of this file; pages consume it.
   NOTE: h2/h3 are deliberately NOT forced here. On /marketplace and
   /portfolios those levels are used for card titles as well as section
   titles (h2 renders at 38.4, 29.44 AND 24.8px on one page), so unifying
   them is a markup-semantics fix, not a font-size fix. See the audit notes. */
html[data-surface="public"] body main h1 {
    font-size: var(--pub-type-hero);
    line-height: 1.06;
    letter-spacing: -0.02em;
    font-weight: 700;
}

/* ---- Elevation: the OS shadows are tuned for a black canvas ------------- */
/* /marketplace and /portfolios were painting oklch(0.06 0.02 252 / 0.5) and
   rgba(6,10,22,0.55), dark-mode drop shadows, onto #fafaf9, which is why
   their cards looked smudged next to the flat cards on /services. Anything
   that still wants elevation on the light surface asks for a --pub-elev-* level. */
html[data-surface="public"] :is(.pf-card, .am-card, .dh-card, .marketplace-card, .card, .panel) {
    box-shadow: none;
}

/* ---- Sections: open bands, cards only where comparison happens --------- */
html:is([data-surface="public"], [data-color-mode="light"]) .section-block,
html:is([data-surface="public"], [data-color-mode="light"]) .vt-section {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    transition: none;
}
html:is([data-surface="public"], [data-color-mode="light"]) .section-block:hover {
    border-color: transparent;
    box-shadow: none;
    transform: none;
}
/* Comparable content keeps its card shape, sharper now. */
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.vt-package, .vt-step, .vt-proof-card, .meta-card, .panel, .vt-card) {
    background: var(--brand-surface);
    border: 1px solid var(--brand-gray);
    border-radius: var(--pub-radius-md);
    box-shadow: none;
}
html:is([data-surface="public"], [data-color-mode="light"]) .vt-package--featured {
    border-color: var(--brand-teal);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vt-package__flag {
    color: var(--brand-red);
    background: rgba(158, 41, 30, 0.08);
}
/* Step number badges ride the teal, not blue. */
html:is([data-surface="public"], [data-color-mode="light"]) .vt-step__index {
    background: var(--brand-teal-soft);
    color: var(--brand-teal);
    border: 1px solid rgba(22, 67, 70, 0.25);
}

/* ---- Buttons: two vocabularies, teal and quiet ------------------------- */
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.button-primary, .apply-button, .wiz-nav-btn--primary) {
    background: var(--brand-teal);
    color: #ffffff;
    border: 1px solid transparent;
    border-radius: var(--pub-radius-sm);
    box-shadow: none;
    background-image: none;
    text-shadow: none;
    font-weight: 600;
    transition: background-color 180ms ease, transform 180ms ease;
}
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.button-primary, .apply-button, .wiz-nav-btn--primary):hover {
    background: var(--brand-teal-deep);
    background-image: none;
    transform: translateY(-1px);
    box-shadow: none;
}
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.button-secondary, .button-ghost, .ghost-button, .wiz-nav-btn--ghost) {
    background: var(--brand-surface);
    background-image: none;
    color: #45585c;
    border: 1px solid var(--ds-border-strong);
    border-radius: var(--pub-radius-sm);
    box-shadow: none;
    font-weight: 600;
    transition: border-color 180ms ease, color 180ms ease;
}
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.button-secondary, .button-ghost, .ghost-button, .wiz-nav-btn--ghost):hover {
    border-color: var(--brand-teal);
    color: var(--brand-ink);
    box-shadow: none;
    transform: none;
}
html:is([data-surface="public"], [data-color-mode="light"])
    :is(a, button, input, select, textarea, [tabindex]):focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
    /* No border-radius here: the outline follows each element's own radius;
       forcing one visibly snapped pill chips square while focused. */
}

/* ---- Wizard chrome ------------------------------------------------------ */
html:is([data-surface="public"], [data-color-mode="light"]) .sell-wizard-progress,
html:is([data-surface="public"], [data-color-mode="light"]) .sell-wizard-track {
    background: rgba(24, 43, 48, 0.1);
}
html:is([data-surface="public"], [data-color-mode="light"]) .sell-wizard-dot {
    background: rgba(24, 43, 48, 0.22);
}
html:is([data-surface="public"], [data-color-mode="light"]) .sell-wizard-dot.is-done {
    background: rgba(22, 67, 70, 0.55);
}
html:is([data-surface="public"], [data-color-mode="light"]) .sell-wizard-dot.is-on {
    background: var(--brand-teal);
}
html:is([data-surface="public"], [data-color-mode="light"]) .wiz-mini input,
html:is([data-surface="public"], [data-color-mode="light"]) .wiz-mini select,
html:is([data-surface="public"], [data-color-mode="light"]) .sell-wizard input,
html:is([data-surface="public"], [data-color-mode="light"]) .sell-wizard select,
html:is([data-surface="public"], [data-color-mode="light"]) .sell-wizard textarea {
    background: var(--brand-surface);
    border: 1px solid var(--ds-border-strong);
    color: var(--brand-ink);
    border-radius: var(--pub-radius-sm);
}
html:is([data-surface="public"], [data-color-mode="light"])
    .sell-wizard
    :is(input, select, textarea)::placeholder {
    color: #5e6f72;
}

/* ---- Chips -------------------------------------------------------------- */
/* Static tags, not filters, see the radius note at the top of this file. The
   specialties section alone renders ten of these in a row; as pills they were
   the single biggest source of the "rounded-full everywhere" read. */
html:is([data-surface="public"], [data-color-mode="light"]) :is(.vt-chip, .preview-chip) {
    background: var(--brand-surface);
    border: 1px solid var(--brand-gray);
    color: #45585c;
    border-radius: var(--pub-radius-sm);
    box-shadow: none;
}
html:is([data-surface="public"], [data-color-mode="light"]) .vt-chip--accent {
    border-color: var(--brand-teal);
    color: var(--brand-teal);
    background: var(--brand-teal-soft);
}

/* ---- Status is semantic, never decorative ------------------------------- */
html:is([data-surface="public"], [data-color-mode="light"]) [data-state="success"] {
    color: var(--ds-success);
}
html:is([data-surface="public"], [data-color-mode="light"]) [data-state="warning"] {
    color: var(--ds-warning);
}
html:is([data-surface="public"], [data-color-mode="light"]) [data-state="danger"],
html:is([data-surface="public"], [data-color-mode="light"]) .wiz-error {
    color: var(--ds-danger);
}

/* ---- Footer ------------------------------------------------------------- */
/* A real commercial footer on the light canvas; the brand book's
   teal-to-brick gradient survives as the closing band (.vd-footer__band). */
html:is([data-surface="public"], [data-color-mode="light"]) .vd-footer {
    background: var(--brand-surface);
    border-top: 1px solid var(--brand-gray);
    color: var(--brand-ink);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-footer__brand p {
    color: #45585c;
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-footer__label {
    color: #5e6f72;
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-footer .footer-link {
    color: #45585c;
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-footer .footer-link:hover {
    color: var(--brand-ink);
}
html:is([data-surface="public"], [data-color-mode="light"]) .vd-footer__legal {
    border-top: 1px solid rgba(24, 43, 48, 0.1);
    color: #5e6f72;
}

/* ---- Network proof strip: boxed, readable, honest ----------------------- */
html:is([data-surface="public"], [data-color-mode="light"]) .home-proof-strip div {
    background: var(--brand-surface);
    border: 1px solid var(--brand-gray);
    border-radius: var(--pub-radius-md);
    box-shadow: none;
}
html:is([data-surface="public"], [data-color-mode="light"]) .home-proof-strip strong {
    color: var(--brand-ink);
}
html:is([data-surface="public"], [data-color-mode="light"]) .home-proof-strip span {
    color: #5e6f72;
}

/* ---- Shared components, snapped to the canonical scale ------------------
   These primitives predate --type-*, so each picked its own near-miss size.
   Measured on one published portfolio: .ghost-button rendered at 14px, 13px
   AND 12.48px depending on which block it sat in, the same component with
   three identities on a single screen. The others sat below the 13px caption
   floor or 2px off a neighbouring step. The snap happens here, scoped to the
   surface under audit, rather than in the shared sheets: the OS keeps its own
   density until that is changed deliberately. */
html[data-surface="public"] :is(.ghost-button, .button-secondary) {
    font-size: var(--type-small);
}
html[data-surface="public"] :is(.preview-chip, .status-pill, .asset-rating) {
    font-size: var(--type-caption);
}
html[data-surface="public"] :is(.asset-card-summary, .asset-price-compare) {
    font-size: var(--type-small);
}
/* Media tiles carried the only 20px corner on the page. */
html[data-surface="public"] .media-card {
    border-radius: var(--pub-radius-lg);
}
html[data-surface="public"] .status-pill {
    border-radius: var(--pub-radius-sm);
}

/* ---- Motion discipline -------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html:is([data-surface="public"], [data-color-mode="light"]) * {
        animation: none !important;
        transition: none !important;
    }
}

/* ---- Fixed-color brand imagery ------------------------------------------ */
/* The sign-in modal embeds the near-white mark as an <img>; on light
   surfaces pull it down to ink so it does not vanish on the white card. */
html:is([data-surface="public"], [data-color-mode="light"]) .global-login-brand__mark img {
    filter: brightness(0.16);
}

/* ---- Modals ------------------------------------------------------------
   The sign-in modal is the ONLY modal a signed-out visitor ever opens, and it
   is rendered by the shared shell on every commercial route, so it was the
   one component guaranteed to be seen in this state and guaranteed to be
   broken in it. Its parts are drawn in design-system.css with hard-coded dark
   oklch fills (13-14% lightness panels, a near-black provider row) while this
   file repoints the text tokens to ink. Ink on 13% lightness is invisible: the
   headline, "Choose a sign-in method" and all three provider names disappeared
   completely, and the only things that survived were the parts with a
   hard-coded LIGHT colour of their own, the mint step eyebrow and the gray
   provider captions, which is exactly the signature of a component missed by
   a foreground-only theme.

   So these rules pair every one of them: no foreground is set here without the
   background it sits on. They are scoped on the shared selector rather than
   data-color-mode alone so the modal is still readable on a commercial route
   with JavaScript disabled, where nothing stamps a colour mode.
   ------------------------------------------------------------------------ */

/* The sheet. light-mode.css carries an equivalent rule, but only under
   html[data-color-mode="light"]; this is the no-JS/public-surface half. */
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.modal-content, .figma-modal-card) {
    background: var(--brand-surface, #ffffff);
    border-color: var(--brand-gray, #d8d7d2);
    color: var(--ds-text-body);
}

/* The scrim stays dark, on a light canvas a light scrim separates nothing,
   but loses the mint bloom, which was tuned to glow against black. */
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.figma-modal, .global-login-modal, .global-logout-modal)
    .modal-backdrop {
    background: rgba(24, 43, 48, 0.32);
    background-image: none;
}

/* A near-white glyph on a 8%-white fill: on the dark card that is a quiet
   close button, on a white card it is nothing at all. */
html:is([data-surface="public"], [data-color-mode="light"]) .modal-close {
    background: var(--brand-sunken, #e7e6e0);
    border-color: var(--brand-gray, #d8d7d2);
    color: var(--brand-ink, #182b30);
}
html:is([data-surface="public"], [data-color-mode="light"]) .modal-close:hover {
    background: var(--brand-gray, #d8d7d2);
    border-color: var(--brand-teal, #164346);
}

/* Pale mint on a 10% accent wash, ~1.6:1 on white. */
html:is([data-surface="public"], [data-color-mode="light"]) .figma-modal-kicker {
    background: var(--brand-teal-soft, #eef4f3);
    border-color: color-mix(in srgb, var(--brand-teal) 26%, transparent);
    color: var(--brand-teal-deep, #0f3134);
}

/* The two step panels and the provider rows: dark fills that the ink text was
   being painted onto. The stage panel is the recessed one, the providers are
   raised cards on it, which is the same depth story the dark version tells. */
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.global-login-stage, .global-login-next) {
    background: var(--brand-sunken, #e7e6e0);
    border-color: var(--brand-gray, #d8d7d2);
    color: var(--ds-text-body);
}
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.global-login-stage, .global-login-next)
    span {
    color: var(--brand-teal-deep, #0f3134);
}
html:is([data-surface="public"], [data-color-mode="light"]) .global-login-next p {
    color: var(--ds-text-muted);
}
/* 0.72 on a light field reads as a rendering fault rather than a disabled
   step; the ink already carries "not yet" without dissolving the panel. */
html:is([data-surface="public"], [data-color-mode="light"]) .global-login-next {
    opacity: 1;
}
html:is([data-surface="public"], [data-color-mode="light"]) .global-login-next strong {
    color: var(--ds-text-muted);
}

html:is([data-surface="public"], [data-color-mode="light"]) .global-login-provider {
    background: var(--brand-surface, #ffffff);
    border-color: var(--brand-gray, #d8d7d2);
    color: var(--brand-ink, #182b30);
}
html:is([data-surface="public"], [data-color-mode="light"])
    :is(.global-login-provider:hover, .global-login-provider:focus-visible) {
    background: var(--brand-teal-soft, #eef4f3);
    border-color: var(--brand-teal, #164346);
    color: var(--brand-ink, #182b30);
}
/* The recommended row keeps its "this one" weight, in the brand's teal
   instead of the OS mint gradient. */
html:is([data-surface="public"], [data-color-mode="light"])
    .global-login-provider--primary {
    background: var(--brand-teal-soft, #eef4f3);
    border-color: var(--brand-teal, #164346);
    color: var(--brand-ink, #182b30);
}
html:is([data-surface="public"], [data-color-mode="light"]) .global-login-provider small {
    color: var(--ds-text-muted);
}
/* The provider tiles are already a white square; on a white card they need an
   edge or the Discord/Google/GitHub marks float unattached. */
html:is([data-surface="public"], [data-color-mode="light"])
    .global-login-provider__icon {
    background: var(--brand-surface, #ffffff);
    border: 1px solid var(--brand-gray, #d8d7d2);
    color: var(--brand-ink, #182b30);
}

/* Same family, same fault: the logout modal's mark is a pale red drawn for a
   near-black card and lands at ~2:1 on white. */
html:is([data-surface="public"], [data-color-mode="light"]) .global-logout-card__mark {
    background: color-mix(in srgb, var(--brand-red) 10%, #ffffff);
    border-color: color-mix(in srgb, var(--brand-red) 32%, transparent);
    color: var(--brand-red-deep, #7b241e);
}

/* ---- Feature/spotlight slab -------------------------------------------- */
/* .am-feature's backdrop is the listing image blurred and dimmed for the
   dark surface; on light it reads as a muddy gray slab under ink text.
   Light contexts get a white card with the image as a whisper of tint. */
html:is([data-surface="public"], [data-color-mode="light"]) .am-feature {
    background: var(--brand-surface, #ffffff);
    border-color: var(--brand-gray, #d8d7d2);
}
html:is([data-surface="public"], [data-color-mode="light"]) .am-feature__backdrop {
    filter: blur(64px) saturate(0.85) brightness(1.05);
    opacity: 0.16;
}
/* The backdrop carries a second, opaque dark overlay for the OS shell. The
   filter above lightened the image but left that overlay painting a near-black
   slab under ink text, the spotlight's headline, tagline and rating were
   unreadable. On light the overlay becomes the white canvas it sits on. */
html:is([data-surface="public"], [data-color-mode="light"]) .am-feature__backdrop::after {
    background: linear-gradient(
        100deg,
        rgba(255, 255, 255, 0.55),
        rgba(255, 255, 255, 0.92)
    );
}
/* The eyebrow mixes the accent toward white for the dark slab; on the light
   slab it has to travel toward ink instead or it washes out. */
html:is([data-surface="public"], [data-color-mode="light"]) .am-feature__eyebrow {
    color: var(--brand-red);
}
/* The artwork's 60px drop shadow and white hairline read as depth on the dark
   shell and as grime on the canvas. Outline it instead. */
html:is([data-surface="public"], [data-color-mode="light"]) .am-feature__media {
    background: var(--ds-canvas-raised);
    border-color: var(--brand-gray);
    box-shadow: none;
}
