/* =============================================================================
   PrivacyWall Design System — Tokens
   -----------------------------------------------------------------------------
   Layer 1  Primitives  ....  raw values, never used directly in components
   Layer 2  Semantic    ....  theme-aware aliases, this is what components use
   Layer 3  Scales      ....  type / space / radius / shadow / motion / layout

   Theming
     <html class="light">  -> light theme (default)
     <html class="dark">   -> dark theme
     <html>                -> follows prefers-color-scheme
   The `.light` / `.dark` class on <html> mirrors the production PrivacyWall
   apps (search + maps), so the same markup works in both codebases.
   ============================================================================= */

/* ---------------------------------------------------------------------------
   FONT
   --------------------------------------------------------------------------- */
/* Vendored so the design system works offline. In the applications, keep
   pointing at the production CDN — the family name and the fallback stack are
   what matter, not where the file comes from. */
/* Inter, vendored as four discrete weights — the same files the product
   serves. This is deliberately NOT the variable font: the build shipped as
   "Inter-Variable" carries no usable wght axis, so a single face registered
   across `100 900` renders 400 and 700 identically and every weight in the
   system collapses to one. Four static faces cannot silently do that. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/Inter-Regular.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../assets/fonts/Inter-Medium.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../assets/fonts/Inter-SemiBold.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../assets/fonts/Inter-Bold.woff2") format("woff2");
}

/* =============================================================================
   LAYER 1 — PRIMITIVES
   ============================================================================= */
:root {
  /* -- Gray — the canonical neutral ramp.
     One scale for both themes. Light mode reads it from the top, dark mode from
     the bottom. Only two steps differ per theme (25 and 900); those overrides
     live in the dark block below. */
  --pw-color-white:      #ffffff;
  --pw-color-gray-25:    #fefefe;
  --pw-color-gray-50:    #f5f6f6;
  --pw-color-gray-100:   #e5e7e8;
  --pw-color-gray-200:   #cdd0d4;
  --pw-color-gray-300:   #abafb5;
  --pw-color-gray-400:   #808790;
  --pw-color-gray-500:   #656b75;
  --pw-color-gray-600:   #575b63;
  --pw-color-gray-700:   #4a4d54;
  --pw-color-gray-800:   #414349;
  --pw-color-gray-900:   #3a3c3f;
  --pw-color-gray-950:   #202124;

  /* ---------------------------------------------------------------------------
     PLAY  —  the colours of the tool widgets' objects
     A wheel's segments, a die's facets, a pointer's brass edge. These are not
     chrome, not state and not data: they are the paint on a physical thing, so
     they are FIXED in both themes for the same reason the brand colours are. A
     wheel whose segments change hue when the page goes dark is a different
     wheel, and the reader is being asked to remember which one they spun.

     Values are the production widgets' own, transcribed from the reference
     builds in privacywall-widgets/ rather than matched by eye — a pastel picked
     to look close is a pastel that is wrong in a screenshot comparison.
     --------------------------------------------------------------------------- */

  /* Spinner wheel. Index 0 is the segment whose leading edge sits at 12 o'clock;
     the rest follow clockwise. There are exactly as many colours as segments. */
  --pw-play-1: #ff8fa3;   /* pink   */
  --pw-play-2: #ffd166;   /* yellow */
  --pw-play-3: #9be7c4;   /* mint   */
  --pw-play-4: #7fc8f8;   /* sky    */
  --pw-play-5: #c5a3ff;   /* lilac  */
  --pw-play-6: #ffb38a;   /* peach  */
  --pw-play-ink:  #2b2140;              /* the numerals, dark enough on all six */
  --pw-play-seam: rgba(43, 33, 64, .10); /* the hairline between two pastels */
  --pw-play-pointer:       #ffd95a;
  --pw-play-pointer-edge:  #b87b00;
  --pw-play-pointer-shine: #fff8d6;
  --pw-play-hub:           #ff5c8a;

  /* Dice. Four tones per die, ordered light to dark, so a flat SVG of polygons
     reads as a lit solid. Assigned by SIDE COUNT and not by rank — D4 is cyan
     and D20 is pink — which is how the set is recognised at a glance. */
  --pw-die-cyan-1:   #7ee7ff;  --pw-die-cyan-2:   #27d8ff;  --pw-die-cyan-3:   #0d91e8;  --pw-die-cyan-4:   #036aac;
  --pw-die-red-1:    #ff9094;  --pw-die-red-2:    #ff5d64;  --pw-die-red-3:    #dc2626;  --pw-die-red-4:    #991b1b;
  --pw-die-orange-1: #ffd089;  --pw-die-orange-2: #ffbe4d;  --pw-die-orange-3: #f97316;  --pw-die-orange-4: #b8480c;
  --pw-die-purple-1: #d3b3ff;  --pw-die-purple-2: #bd8cff;  --pw-die-purple-3: #7c3aed;  --pw-die-purple-4: #5b21b6;
  --pw-die-green-1:  #91efb0;  --pw-die-green-2:  #5ee689;  --pw-die-green-3:  #16a34a;  --pw-die-green-4:  #166534;
  --pw-die-pink-1:   #ffa3d6;  --pw-die-pink-2:   #ff76c7;  --pw-die-pink-3:   #db2777;  --pw-die-pink-4:   #9d174d;
  --pw-die-seam: rgba(0, 0, 0, .18);

  /* Metronome tempo bands. A warmth ramp — slow tempi cool, fast tempi hot — so
     the accent tells you roughly where you are before you read the number. */
  --pw-tempo-largo:      #4f8ef7;
  --pw-tempo-adagio:     #9b59f5;
  --pw-tempo-andante:    #22d3ee;
  --pw-tempo-moderato:   #10b981;
  --pw-tempo-allegretto: #f59e0b;
  --pw-tempo-allegro:    #f97316;
  --pw-tempo-presto:     #ef4444;

  /* Meditate. The one widget that commits to a single treatment in both themes
     rather than following the page — a breathing session is a room you step
     into, and a room does not repaint itself when the lights outside change.
     Everything on it is white at an alpha, so only the ground needs naming. */
  --pw-calm-from:  #1967d2;
  --pw-calm-to:    #174ea6;
  --pw-calm-lift:  rgba(138, 180, 248, .20);  /* the light behind the orb */
  --pw-calm-ink:   #1967d2;                   /* on the white play button */
  --pw-calm-hold:  #ffde82;                   /* the gold a hold turns */
  --pw-calm-edge:  rgba(23, 78, 166, .08);
  --pw-calm-phase: hsla(0, 0%, 100%, .82);
  /* Pills. Three sets: the neutral one, the blue duration row and the gold
     pattern row — gold because it is the family the orb turns during a hold, so
     the row predicts what a hold will look like before you choose one. */
  --pw-calm-pill-bg:         hsla(0, 0%, 100%, .08);
  --pw-calm-pill-edge:       hsla(0, 0%, 100%, .20);
  --pw-calm-pill-fg:         hsla(0, 0%, 100%, .70);
  --pw-calm-pill-bg-hover:   hsla(0, 0%, 100%, .16);
  --pw-calm-pill-edge-hover: hsla(0, 0%, 100%, .30);
  --pw-calm-pill-bg-on:      hsla(0, 0%, 100%, .22);
  --pw-calm-pill-edge-on:    hsla(0, 0%, 100%, .40);
  --pw-calm-time-bg:         rgba(137, 180, 248, .14);
  --pw-calm-time-edge:       rgba(137, 180, 248, .26);
  --pw-calm-time-fg:         rgba(232, 240, 254, .84);
  --pw-calm-time-bg-on:      rgba(169, 216, 255, .34);
  --pw-calm-time-edge-on:    rgba(209, 231, 255, .56);
  --pw-calm-hold-bg:         rgba(255, 222, 130, .12);
  --pw-calm-hold-edge:       rgba(255, 222, 130, .24);
  --pw-calm-hold-fg:         rgba(255, 245, 214, .88);
  --pw-calm-hold-bg-on:      rgba(255, 222, 130, .32);
  --pw-calm-hold-edge-on:    rgba(255, 238, 188, .52);
  --pw-calm-hold-fg-on:      #fff7d6;
  /* The orb, and the light it catches. */
  --pw-calm-orb-1:    hsla(0, 0%, 100%, .96);
  --pw-calm-orb-2:    rgba(232, 240, 254, .86);
  --pw-calm-orb-3:    rgba(210, 227, 252, .78);
  --pw-calm-orb-glow: rgba(232, 240, 254, .34);
  --pw-calm-orb-lip:  hsla(0, 0%, 100%, .85);
  --pw-calm-ring:     hsla(0, 0%, 100%, .55);
  --pw-calm-halo:     rgba(232, 240, 254, .08);
  /* The two decorative animations. The dots are the drifting bokeh field; the
     pulse is the ring that departs the play button every 1.2s, and it turns
     gold on a hold with everything else. */
  --pw-calm-dot:        hsla(0, 0%, 100%, .18);
  --pw-calm-pulse:      rgba(232, 240, 254, .32);
  --pw-calm-pulse-hold: rgba(255, 222, 130, .38);

  /* The Other-tools strip. One pastel pair per tool, always at 135deg, chosen
     so the art sitting on it stays legible — they are the ground for a fixed
     drawing, which is why they are fixed too. */
  --pw-toolart-coin-1:      #fff6d7;  --pw-toolart-coin-2:      #ffe1a6;
  --pw-toolart-spinner-1:   #fff8e7;  --pw-toolart-spinner-2:   #e8efff;
  --pw-toolart-dice-1:      #fff1f7;  --pw-toolart-dice-2:      #eef6ff;
  --pw-toolart-metronome-1: #fff4df;  --pw-toolart-metronome-2: #ffe7cc;
  --pw-toolart-tuner-1:     #ecf6ff;  --pw-toolart-tuner-2:     #dceefe;
  --pw-toolart-meditate-1:  #eef0ff;  --pw-toolart-meditate-2:  #ece4ff;
  --pw-toolart-weather-1:   #e9f7ff;  --pw-toolart-weather-2:   #dceeff;
  --pw-toolart-coords-1:    #edf8f0;  --pw-toolart-coords-2:    #ddefe4;
  --pw-toolart-near-1:      #fff7e9;  --pw-toolart-near-2:      #ffead2;
  --pw-toolart-compare-1:   #fff0f4;  --pw-toolart-compare-2:   #ffe1ea;
  --pw-toolart-capital-1:   #f4f5ff;  --pw-toolart-capital-2:   #e3e6ff;
  --pw-toolart-holidays-1:  #fff7df;  --pw-toolart-holidays-2:  #ffe8bf;
  --pw-toolart-population-1:#eef7ff;  --pw-toolart-population-2:#dce9ff;

  /* ---------------------------------------------------------------------------
     BRAND  —  other companies' colours, for sign-in buttons that require them
     Fixed in both themes, because they belong to their owners. Reproduced from
     each company's published brand guidance; see assets/brand/README.md. They
     are named, not pasted at the call site, for the same reason every other
     colour here is: a value written into a component is a value nobody can find
     again, and the sixth time someone needs Facebook blue they will guess.
     --------------------------------------------------------------------------- */
  --pw-brand-apple:    #000000;
  --pw-brand-facebook: #1877f2;
  --pw-brand-discord:  #5865f2;
  --pw-brand-linkedin: #0a66c2;
  --pw-brand-github:   #24292f;
  --pw-brand-x:        #000000;
  --pw-brand-reddit:   #ff4500;
  --pw-brand-whatsapp: #25d366;
  --pw-brand-telegram: #26a5e4;
  --pw-brand-youtube:  #ff0033;
  --pw-brand-bluesky:  #1185fe;
  --pw-color-black:      #000000;

  /* -- Brand blue — canonical ramp. 600 is the action colour. */
  --pw-color-brand-25:   #eef5ff;
  --pw-color-brand-50:   #deebff;
  --pw-color-brand-100:  #cee1ff;
  --pw-color-brand-200:  #adcdff;
  --pw-color-brand-300:  #8db8fe;
  --pw-color-brand-400:  #6ca4fe;
  --pw-color-brand-500:  #4c90fe;
  --pw-color-brand-600:  #3d80ec;   /* primary action, links, active nav */
  --pw-color-brand-700:  #2e70db;   /* action hover */
  --pw-color-brand-800:  #1f60c9;   /* action pressed */
  --pw-color-brand-900:  #1050b8;
  --pw-color-brand-950:  #0948af;

  /* -- Link (search results use the classic result-link blue / visited purple) */
  --pw-color-link:              #1a0dab;
  --pw-color-link-visited:      #6b21a8;
  --pw-color-link-dark:         #8ab4f8;
  --pw-color-link-visited-dark: #c58af9;

  /* -- Success */
  --pw-color-success-25:  #f0fdf4;
  --pw-color-success-50:  #ecfdf3;
  --pw-color-success-100: #dcfae6;
  --pw-color-success-150: #d1fadf;
  --pw-color-success-200: #6ce9a6;
  --pw-color-success-300: #a6f4c5;
  --pw-color-success-400: #32d583;
  --pw-color-success-500: #12b76a;
  --pw-color-success-600: #079455;
  --pw-color-success-650: #039855;
  --pw-color-success-700: #027a48;
  --pw-color-success-800: #074d31;

  /* -- Warning */
  --pw-color-warning-25:  #fffcf5;
  --pw-color-warning-50:  #fef0c7;
  --pw-color-warning-100: #fedf89;
  --pw-color-warning-400: #fec84b;
  --pw-color-warning-500: #f79009;
  --pw-color-warning-600: #dc6803;
  --pw-color-warning-700: #b54708;
  --pw-color-warning-800: #93370d;

  /* -- Danger */
  --pw-color-danger-25:  #fef3f2;
  --pw-color-danger-50:  #fee4e2;
  --pw-color-danger-150: #fecdca;
  --pw-color-danger-250: #fda29b;
  --pw-color-danger-350: #f97066;
  --pw-color-danger-500: #f04438;
  --pw-color-danger-600: #d92d20;
  --pw-color-danger-700: #b42318;
  --pw-color-danger-800: #7a271a;

  /* -- Info */
  --pw-color-info-25:  #f5f8ff;
  --pw-color-info-50:  #eff8ff;
  --pw-color-info-500: #0ba5ec;
  --pw-color-info-600: #1d9bf0;
  --pw-color-info-700: #026aa2;

  /* -- Accent (AI surfaces) */
  --pw-color-purple-50:  #f4f3ff;
  --pw-color-purple-100: #ebe9fe;
  --pw-color-purple-500: #7a5af8;
  --pw-color-purple-600: #7f56d9;
  --pw-color-purple-700: #6941c6;

  /* -- Vertical accents
     Named exceptions, not a second brand. Shopping's primary action is amber in
     the approved designs; everything else on that surface still uses the blue
     action tokens so the page keeps a single primary. */
  --pw-accent-shop:        #f59517;
  --pw-accent-shop-hover:  #dc7f0b;
  --pw-accent-shop-active: #b8690a;
  --pw-accent-shop-fg:     #ffffff;

  /* -- Brand identity (shield mark colours — logo only, never UI fills; the
     AI marks use them through --pw-ai-mesh-*) */
  --pw-brand-shield-red:   #dc422f;
  --pw-brand-shield-amber: #efac36;
  --pw-brand-shield-cyan:  #00aad7;
  --pw-brand-shield-ink:   #263947;
}

/* =============================================================================
   LAYER 3 — SCALES  (theme-independent)
   ============================================================================= */
:root {
  /* -- Type ------------------------------------------------------------------ */
  --pw-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
                  Helvetica, Arial, sans-serif;
  --pw-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
                  "Liberation Mono", monospace;
  /* Arabic script. Inter has no Arabic, so Arabic text is set in the
     platform's own Arabic face, with Inter still first for any Latin inside. */
  --pw-font-arabic: "Inter", "SF Arabic", "Geeza Pro", "Segoe UI", "Noto Sans Arabic", Tahoma, sans-serif;

  /* Inter ships italics for each weight; use the family's own italics, never
     a synthesised oblique. */
  --pw-font-weight-regular:  400;
  --pw-font-weight-medium:   500;
  --pw-font-weight-semibold: 600;
  --pw-font-weight-bold:     700;

  /* text-* is UI copy, display-* is headline copy. 14/20 (text-sm) is the
     canonical body size and the one every product screen is measured against. */
  --pw-text-xs-size:       12px;  --pw-text-xs-line:       18px;
  --pw-text-sm-size:       14px;  --pw-text-sm-line:       20px;
  --pw-text-md-size:       16px;  --pw-text-md-line:       24px;
  --pw-text-lg-size:       18px;  --pw-text-lg-line:       28px;
  --pw-text-xl-size:       20px;  --pw-text-xl-line:       30px;
  --pw-display-xs-size:    24px;  --pw-display-xs-line:    32px;
  --pw-display-sm-size:    30px;  --pw-display-sm-line:    38px;
  --pw-display-md-size:    36px;  --pw-display-md-line:    44px;
  --pw-display-lg-size:    48px;  --pw-display-lg-line:    60px;
  --pw-display-xl-size:    60px;  --pw-display-xl-line:    72px;
  --pw-display-2xl-size:   72px;  --pw-display-2xl-line:   90px;

  --pw-tracking-tight:  -0.02em;
  --pw-tracking-snug:   -0.01em;
  --pw-tracking-normal: 0;
  --pw-tracking-wide:   0.04em;
  --pw-tracking-caps:   0.08em;

  /* -- Space (4px base; token number = value / 2) ---------------------------- */
  --pw-space-0:   0px;
  --pw-space-1:   2px;
  --pw-space-2:   4px;
  --pw-space-3:   6px;
  --pw-space-4:   8px;
  --pw-space-5:   10px;
  --pw-space-6:   12px;
  --pw-space-7:   14px;
  --pw-space-8:   16px;
  --pw-space-10:  20px;
  --pw-space-12:  24px;
  --pw-space-14:  28px;
  --pw-space-16:  32px;
  --pw-space-20:  40px;
  --pw-space-24:  48px;
  --pw-space-28:  56px;
  --pw-space-32:  64px;
  --pw-space-40:  80px;
  --pw-space-48:  96px;

  /* -- Radius ---------------------------------------------------------------- */
  --pw-radius-none:   0px;
  --pw-radius-xs:     4px;
  --pw-radius-sm:     6px;
  --pw-radius-md:     8px;
  --pw-radius-lg:     12px;
  --pw-radius-xl:     16px;
  --pw-radius-2xl:    20px;
  --pw-radius-3xl:    24px;
  --pw-radius-pill:   999px;
  --pw-radius-circle: 50%;

  /* -- Backdrop blur ----------------------------------------------------------
     Two strengths, because the two surfaces that use one are asking for
     different things. A dialog's scrim keeps the page behind it legible — you
     are meant to see what you are on top of, and 2px says "behind" without
     saying "gone". A photo viewer is the opposite: the whole point is that
     nothing behind it competes, so it blurs past the point where anything back
     there can be read. Neither value inverts, so both are declared once. */
  --pw-blur-scrim:    2px;
  --pw-blur-lightbox: 28px;

  /* -- Motion ---------------------------------------------------------------- */
  --pw-duration-instant: 80ms;
  --pw-duration-fast:    120ms;
  --pw-duration-base:    180ms;
  --pw-duration-slow:    240ms;
  --pw-duration-slower:  320ms;
  /* A readout rolling to a new value, which is not a transition and does not
     belong on the transition scale. A panel opening is over as soon as you have
     understood it; a number counting has to be legible WHILE it moves, or the
     values between are a smear and the count may as well not have happened. */
  --pw-duration-readout: 480ms;
  --pw-ease-out:    cubic-bezier(0.22, 1, 0.36, 1);
  --pw-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --pw-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* -- Icon ------------------------------------------------------------------
     Stroke is in viewBox units (the set is drawn on a 24 grid at weight 2), so
     the rendered thickness scales with the rendered size:
       14px -> 1.17   16px -> 1.33   20px -> 1.67   24px -> 2.00   28px -> 2.33 */
  --pw-icon-stroke: 2;
  --pw-icon-xs: 14px;
  --pw-icon-sm: 16px;
  --pw-icon-md: 20px;
  --pw-icon-lg: 24px;
  --pw-icon-xl: 28px;

  /* -- Layout ---------------------------------------------------------------- */
  --pw-rail-width:          64px;   /* maps icon rail (collapsed) */
  --pw-rail-width-expanded: 250px;  /* maps nav expanded */
  --pw-panel-width:         420px;  /* maps side sheet */
  /* Measured off the live SERP rather than chosen here, because the docs are
     wrong the moment they disagree with the page they describe. Four different
     left edges is what the page actually does: logo 112, field 184, tabs and
     filters 200, results 212. They are named separately rather than derived
     from one another so that correcting one does not silently move the rest. */
  --pw-serp-content-width:  700px;  /* search results column */
  --pw-serp-gutter:         212px;  /* left edge of the results column */
  --pw-serp-gutter-end:      80px;  /* right gutter — measured, and it exists */
  --pw-serp-gutter-phone:    24px;  /* both edges once the page is a phone */
  --pw-serp-rail-width:     420px;  /* knowledge panel column */
  --pw-serp-column-gap:      60px;  /* between the results and the rail */
  --pw-serp-rail-pad:        36px;  /* inside the rail, past its rule */
  --pw-serp-nav-inset:      200px;  /* left edge of the tabs and filter rows */
  --pw-serp-logo-inset:     112px;  /* left edge of the logo */
  --pw-serp-logo-size:       40px;  /* the mark in the results header */
  --pw-serp-field-inset:    184px;  /* left edge of the search field */
  /* Derived, so the field's RIGHT edge lands on the results column's right
     edge. It used to be a flat 700 — the same WIDTH as the column, which is not
     the same thing: the field starts at 184 and the column at 212, so two equal
     widths from different left edges put their right edges 28px apart, and the
     search visibly stopped short of everything under it. Ends at
     212 + 700 = 912 either way; this reaches it from 184 instead. */
  --pw-serp-field-width:
    calc(var(--pw-serp-gutter) + var(--pw-serp-content-width) - var(--pw-serp-field-inset));
  --pw-serp-field-height:    52px;  /* the pill itself, not its wrapper */
  --pw-serp-header-height:  168px;  /* home header */
  --pw-serp-header-compact:  90px;  /* results header bar */
  /* Scrolled: the verticals and the filters have gone, and the bar goes with
     them. Holding 90px of chrome up to carry one field spends the height the
     collapse just handed back. */
  --pw-serp-header-condensed: 64px;  /* the bar once the page is scrolled */
  --pw-serp-field-condensed:  44px;  /* the field inside it */
  --pw-serp-tabs-width:     670px;  /* the verticals row's own width */
  --pw-serp-row-gap:     var(--pw-space-5);  /* each side of the chrome's rule */
  --pw-container-max:       1280px;

  /* -- Breakpoints (documentation values; media queries cannot read vars) ----- */
  --pw-bp-xs: 480px;
  --pw-bp-sm: 576px;
  --pw-bp-md: 768px;   /* primary mobile / desktop split */
  --pw-bp-lg: 992px;
  --pw-bp-xl: 1200px;
  --pw-bp-2xl: 1440px;

  /* -- Z-index ---------------------------------------------------------------
     The scrim sits directly BENEATH the lowest surface it dims — never above
     it. Sheets and drawers used to be numbered under the overlay, which meant
     every one of them opened behind its own scrim: fully functional, entirely
     greyed out. Anything added here goes above `overlay` if it is a surface a
     person interacts with, and below it if it is page content. */
  --pw-z-base:      0;
  --pw-z-sticky:    10;
  --pw-z-map-ui:    20;
  --pw-z-header:    30;
  --pw-z-dropdown:  40;
  --pw-z-overlay:   50;   /* scrim */
  --pw-z-sheet:     60;   /* sheet · drawer — above the scrim */
  --pw-z-modal:     70;
  --pw-z-popover:   80;
  --pw-z-toast:     90;
  --pw-z-fullscreen: 100;  /* the fallback when requestFullscreen is refused */
  --pw-z-tooltip:   100;
}

/* =============================================================================
   LAYER 2 — SEMANTIC (LIGHT)
   ============================================================================= */
:root,
html.light,
[data-pw-theme="light"] {
  color-scheme: light;

  /* Surfaces */
  --pw-bg-canvas:         var(--pw-color-white);
  --pw-bg-canvas-subtle:  var(--pw-color-gray-50);
  --pw-bg-surface:        var(--pw-color-white);
  --pw-bg-surface-raised: var(--pw-color-white);
  --pw-bg-subtle:         var(--pw-color-gray-50);
  --pw-bg-muted:          var(--pw-color-gray-50);
  --pw-bg-strong:         var(--pw-color-gray-100);
  --pw-bg-inverse:        var(--pw-color-gray-950);
  --pw-bg-overlay:        rgba(32, 33, 36, 0.45);
  /* Heavier than the dialog scrim above, and deliberately so: a lightbox is the
     one surface whose whole job is that nothing behind it competes. At the
     scrim's 0.45 over a white dialog the wash lands near rgb(155), and white
     text on that is 2.8:1 — the caption and the count were legible only where a
     photograph happened to be behind them. This lands near rgb(71), which
     carries them at 9:1 anywhere on the screen.

     It does not invert. Like `--pw-bg-overlay` it darkens whatever it covers,
     and a pale lightbox in dark mode would light the room up. Written into all
     three blocks at the same value rather than once, so a reader comparing the
     blocks does not find it missing from two of them and assume an oversight. */
  --pw-bg-lightbox:       rgba(0, 0, 0, 0.72);
  /* A control resting ON the scrim, pressed. White at low alpha, so it lifts the
     glyph off whatever the blur has left behind without becoming a shape of its
     own. Does not invert, for the same reason the scrim does not. */
  --pw-bg-on-overlay:     rgba(255, 255, 255, 0.16);
  /* And a step up, for a control that rests VISIBLE on the scrim rather than
     appearing under the pointer. Same material, so the two read as one control
     at two strengths rather than as two different buttons. */
  --pw-bg-on-overlay-strong: rgba(255, 255, 255, 0.28);
  --pw-bg-hover:          var(--pw-color-gray-50);
  /* Hover for a row sitting ON a subtle surface (the app shell's main area is
     bg-subtle). In light, bg-hover IS that surface's colour and the hover
     vanishes; this steps one shade further. Dark has room and keeps bg-hover. */
  --pw-bg-hover-on-subtle: var(--pw-color-gray-100);
  --pw-bg-active:         var(--pw-color-gray-100);
  --pw-bg-selected:       var(--pw-color-brand-50);
  /* Selected, without the claim. `--pw-bg-selected` says brand: this is the
     one you chose and it is OURS. A row of tabs where every option is an
     equal peer — verticals, outbound/return — is choosing, not endorsing,
     and painting the choice blue reads as a brand accent that happens to
     land wherever the finger last was. One step past hover in the neutral
     ramp, so a hovered tab and the selected one stay tellable apart. */
  --pw-bg-selected-neutral: var(--pw-color-gray-100);
  /* -- Tints ---------------------------------------------------------------
  A tinted container and the glyph inside it, as a PAIR. Medallions, list
  marks, chip marks, badges — anything that is a small patch of colour with
  an icon on it — should reach for these rather than picking a ramp step.

  The reason is that a ramp step does not invert. `--pw-color-danger-25` is
  the same near-white in both themes, because only two steps of the grey
  ramp differ per theme; used as a fill it leaves a bright disc burning a
  hole in a dark card, and the glyph on it loses most of its contrast. These
  pairs are defined per theme, so a component that uses them is correct in
  both without knowing which one it is in. */
  --pw-tint-brand-bg:     var(--pw-color-brand-50);
  --pw-tint-brand-fg:     var(--pw-color-brand-600);
  --pw-tint-success-bg:   var(--pw-color-success-50);
  --pw-tint-success-fg:   var(--pw-color-success-650);
  --pw-tint-warning-bg:   var(--pw-color-warning-25);
  --pw-tint-warning-fg:   var(--pw-color-warning-600);
  --pw-tint-danger-bg:    var(--pw-color-danger-25);
  --pw-tint-danger-fg:    var(--pw-color-danger-600);
  --pw-tint-ai-bg:        var(--pw-color-purple-50);
  --pw-tint-ai-fg:        var(--pw-color-purple-600);
  /* The AI surface: brand blue into AI violet, the two hues the product already
     owns. Glows for the fill, a stronger pair for the hairline edge. */
  --pw-ai-glow-a:         rgba(76, 144, 254, 0.13);   /* brand-500 */
  --pw-ai-glow-b:         rgba(122, 90, 248, 0.12);   /* purple-500 */
  --pw-ai-edge-a:         rgba(76, 144, 254, 0.42);
  --pw-ai-edge-b:         rgba(122, 90, 248, 0.46);
  /* The AI mesh: the AI logo's own gradient, cyan into red into amber. The
     orb's and Glance mark's dots are drawn in it, and a Glance's edge and
     working glow are mixed from it. */
  --pw-ai-mesh-a:         #1ab3db;
  --pw-ai-mesh-b:         #dc422f;
  --pw-ai-mesh-c:         #efac36;
  --pw-bg-disabled:       var(--pw-color-gray-100);

  /* Foreground */
  --pw-fg-primary:      var(--pw-color-gray-950);
  --pw-fg-secondary:    var(--pw-color-gray-700);
  --pw-fg-tertiary:     var(--pw-color-gray-500);
  --pw-fg-quaternary:   var(--pw-color-gray-400);
  --pw-fg-disabled:     var(--pw-color-gray-300);
  --pw-fg-inverse:      var(--pw-color-white);
  --pw-fg-brand:        var(--pw-color-brand-600);
  --pw-fg-on-brand:     var(--pw-color-white);
  /* A surface resting ON a brand fill — the badge inside a selected pill, and
     anything else that has to read as a lighter patch of the same button.
     White at low alpha rather than a step of the brand ramp, because the ramp
     inverts and this must not: the fill is saturated in both themes, so what
     sits on it is light in both. Pairs with `--pw-fg-on-brand` above, which is
     white for the same reason. */
  --pw-bg-on-brand:     rgba(255, 255, 255, 0.22);
  /* On the scrim, which is the one surface in the system that does NOT invert:
     `--pw-bg-overlay` is dark in both themes, because it darkens the page it is
     covering and a pale scrim in dark mode would brighten it. So its foreground
     does not invert either — this is white in all three blocks, and that is the
     point of it rather than an oversight. `--pw-fg-inverse` is the wrong token
     here: it is the inverse of the PAGE, so it turns dark in dark mode and
     writes near-black onto a near-black scrim. */
  --pw-fg-on-overlay:   var(--pw-color-white);
  /* And its mirror: text on ARTWORK the page supplied -- a hero's photograph or
     brand gradient. That surface does not invert either, for the plainer reason
     that an image is the same image in both themes, so `--pw-fg-primary` writes
     near-white across a pale hero the moment the reader turns the lights down.
     Every hero in the system is light artwork, so this is the dark ink, fixed.
     `gray-950` and not `--pw-fg-primary`: the RAMP is one scale for both themes
     and only the aliases pick different steps from it, so naming the step is
     how a colour opts out of inverting. Artwork dark enough to need light text
     takes a scrim and `--pw-fg-on-overlay` above, which is the same rule read
     from the other end. */
  --pw-fg-on-artwork:   var(--pw-color-gray-950);
  --pw-fg-link:         var(--pw-color-link);
  --pw-fg-link-visited: var(--pw-color-link-visited);
  --pw-fg-success:      var(--pw-color-success-650);
  --pw-fg-warning:      var(--pw-color-warning-600);
  --pw-fg-danger:       var(--pw-color-danger-600);
  --pw-fg-info:         var(--pw-color-info-600);

  /* Border */
  /* Lighter than `subtle`, for a separator BETWEEN rows rather than around a
     surface. A line dividing two things needs less weight than a line enclosing
     one -- at `subtle` a list of eight rows reads as eight boxes. */
  --pw-border-faint:   var(--pw-color-gray-50);
  --pw-border-subtle:  var(--pw-color-gray-100);
  --pw-border-default: var(--pw-color-gray-200);
  --pw-border-strong:  var(--pw-color-gray-200);
  --pw-border-inverse: var(--pw-color-gray-800);
  --pw-border-brand:   var(--pw-color-brand-600);
  --pw-border-danger:  var(--pw-color-danger-350);
  --pw-border-success: var(--pw-color-success-400);

  /* Action — primary (filled blue) */
  --pw-action-bg:        var(--pw-color-brand-600);
  --pw-action-bg-hover:  var(--pw-color-brand-700);
  --pw-action-bg-active: var(--pw-color-brand-800);
  /* Text-only brand actions need more contrast than a filled button, whose
     contrast comes from its background. These are one step darker. */
  --pw-action-link:        var(--pw-color-brand-700);
  /* Results-header search field: filled at rest, lighter on focus. */
  /* The header field is the surface colour, not a grey fill. A tinted field
     was reading as disabled next to the white chips below it, and the sheen
     that sold the "pressed in" look does nothing on white — so the edge comes
     from a real border, and depth from the shadow on hover and focus. */
  --pw-serp-search-bg:        var(--pw-bg-surface);
  --pw-serp-search-bg-hover:  var(--pw-bg-surface);
  --pw-serp-search-bg-focus:  var(--pw-bg-surface);
  --pw-serp-search-border:    var(--pw-border-default);
  --pw-serp-search-sheen:     transparent;
  --pw-serp-search-ring:      rgba(66, 72, 78, 0.12);
  /* Translucent overlays for controls that sit on an unknown ground — an
     icon button inside a field, a chip on a photo. A fixed grey works on
     white and turns into a hole the moment the surface behind it is tinted. */
  --pw-ink-hover:  rgba(16, 24, 40, 0.07);
  /* The themed half of the brand mark: the fingerprint ridges and the
     "Privacy" wordmark. The shield's brand colours are fixed and are not
     tokens — they never follow the theme. */
  --pw-logo-ink: #263947;
  --pw-ink-active: rgba(16, 24, 40, 0.12);
  --pw-action-link-hover:  var(--pw-color-brand-800);
  --pw-action-link-active: var(--pw-color-brand-900);
  --pw-action-fg:        var(--pw-color-white);
  --pw-action-border:    transparent;

  /* Action — secondary (outlined) */
  --pw-action-2-bg:           var(--pw-color-white);
  --pw-action-2-bg-hover:     var(--pw-color-gray-50);
  --pw-action-2-bg-active:    var(--pw-color-gray-100);
  --pw-action-2-fg:           var(--pw-color-gray-800);
  --pw-action-2-border:       var(--pw-color-gray-200);
  --pw-action-2-border-hover: var(--pw-color-gray-300);

  /* Action — tertiary (ghost) */
  --pw-action-3-bg-hover:  var(--pw-color-gray-50);
  --pw-action-3-bg-active: var(--pw-color-gray-100);
  --pw-action-3-fg:        var(--pw-color-gray-700);

  /* Field */
  --pw-field-bg:           var(--pw-color-white);
  --pw-field-bg-hover:     var(--pw-color-white);
  --pw-field-bg-disabled:  var(--pw-color-gray-100);
  --pw-field-border:       var(--pw-color-gray-200);
  --pw-field-border-hover: var(--pw-color-gray-300);
  --pw-field-border-focus: var(--pw-color-brand-600);
  --pw-field-fg:           var(--pw-color-gray-950);
  --pw-field-placeholder:  var(--pw-color-gray-500);
  --pw-field-icon:         var(--pw-color-gray-400);

  /* Focus */
  --pw-focus-ring-color: rgba(61, 128, 236, 0.28);
  --pw-focus-ring:       0 0 0 4px var(--pw-focus-ring-color);

  /* Elevation */
  --pw-shadow-xs:     0 1px 2px 0 rgba(16, 24, 40, 0.05);
  --pw-shadow-sm:     0 1px 3px 0 rgba(16, 24, 40, 0.10), 0 1px 2px 0 rgba(16, 24, 40, 0.06);
  --pw-shadow-md:     0 4px 8px -2px rgba(16, 24, 40, 0.10), 0 2px 4px -2px rgba(16, 24, 40, 0.06);
  --pw-shadow-lg:     0 12px 16px -4px rgba(16, 24, 40, 0.08), 0 4px 6px -2px rgba(16, 24, 40, 0.03);
  --pw-shadow-xl:     0 20px 24px -4px rgba(16, 24, 40, 0.08), 0 8px 8px -4px rgba(16, 24, 40, 0.03);
  --pw-shadow-2xl:    0 24px 48px -12px rgba(16, 24, 40, 0.18);
  --pw-shadow-3xl:    0 32px 64px -12px rgba(16, 24, 40, 0.14);
  --pw-shadow-modal:  0 24px 48px -12px rgba(16, 24, 40, 0.25);
  /* Overlay — the only edge a control gets when it floats on imagery or on a
     hue. Deliberately heavier than `sm`, with a tight contact layer, because
     it replaces a border rather than accompanying one. */
  --pw-shadow-overlay: 0 1px 2px 0 rgba(16, 24, 40, 0.16), 0 4px 12px -2px rgba(16, 24, 40, 0.16);
  /* For a surface that is not a rectangle. `box-shadow` traces the border
     box, so a shape assembled from two boxes gets two shadows and a seam
     where they meet; `drop-shadow` traces the painted alpha and reads the
     compound shape as one object. Filter-ready, hence a pair rather than a
     box-shadow list. */
  --pw-shadow-drop: drop-shadow(0 8px 12px rgba(16, 24, 40, 0.10)) drop-shadow(0 2px 4px rgba(16, 24, 40, 0.06));
  --pw-shadow-map-ui: var(--pw-shadow-overlay);   /* legacy alias */

  /* Maps rail — a tinted, translucent surface that blurs the canvas behind it.
     Not a solid panel: on narrow layouts the rail sits directly over the map. */
  /* Map canvas — the tile imagery every maps placeholder sits on. One file,
     named once, so every specimen shows the same city and swapping it is a
     single edit. The gradient underneath is a fallback, not decoration: it
     paints if the file is missing, so the docs never render a dead grey box. */
  --pw-map-tile: url("../assets/maps/canvas.svg");
  --pw-map-tile-fallback: linear-gradient(150deg, #e8efe4, #dbe7ef 55%, #efeadf);

  /* Surfaces that sit ON the frosted panel. A solid grey tile on a translucent
     ground reads as a hole: the panel lets the map through and the tile does
     not, so the tile looks pasted on. These are translucent white with a
     hairline — the same map colour comes through at a lower rate, and the tile
     reads as raised out of the panel rather than stuck to it. */
  --pw-frost-fill:        rgba(255, 255, 255, 0.72);
  --pw-frost-fill-hover:  rgba(255, 255, 255, 0.92);
  --pw-frost-fill-active: rgba(255, 255, 255, 1);
  --pw-frost-border:      rgba(255, 255, 255, 0.90);

  --pw-rail-surface: rgba(245, 251, 249, 0.72);
  --pw-rail-blur:    blur(18px) saturate(1.4);

  /* Scrollbar */
  --pw-scrollbar-thumb:       rgba(72, 80, 89, 0.34);
  --pw-scrollbar-thumb-hover: rgba(72, 80, 89, 0.48);

  /* Skeleton */
  --pw-skeleton-base:  var(--pw-color-gray-50);
  --pw-skeleton-sheen: var(--pw-color-gray-100);
}

/* =============================================================================
   LAYER 2 — SEMANTIC (DARK)
   ============================================================================= */
html.dark,
[data-pw-theme="dark"] {
  color-scheme: dark;

  /* The two ramp steps that differ per theme. Everything else is shared. */
  --pw-color-gray-25:  #fafafa;
  /* One step between 800 and 900, so a row separator can sit nearer the ground
     than a surface border does. Dark only: the light ramp has gray-50 already. */
  --pw-color-gray-850: #383a3e;
  --pw-color-gray-900: #2d2f32;

  --pw-bg-canvas:         var(--pw-color-gray-950);
  --pw-bg-canvas-subtle:  var(--pw-color-gray-950);
  --pw-bg-surface:        var(--pw-color-gray-900);
  --pw-bg-surface-raised: var(--pw-color-gray-800);
  --pw-bg-subtle:         var(--pw-color-gray-950);
  --pw-bg-muted:          var(--pw-color-gray-800);
  --pw-bg-strong:         var(--pw-color-gray-700);
  --pw-bg-inverse:        var(--pw-color-gray-50);
  --pw-bg-overlay:        rgba(0, 0, 0, 0.60);
  --pw-bg-lightbox:       rgba(0, 0, 0, 0.72);
  --pw-bg-on-overlay:     rgba(255, 255, 255, 0.16);
  --pw-bg-on-overlay-strong: rgba(255, 255, 255, 0.28);
  --pw-bg-hover:          var(--pw-color-gray-800);
  --pw-bg-hover-on-subtle: var(--pw-color-gray-800);
  --pw-bg-active:         var(--pw-color-gray-700);
  --pw-bg-selected:       rgba(61, 128, 236, 0.20);
  --pw-bg-selected-neutral: var(--pw-color-gray-700);
  /* Tints, inverted. Same pairs, dark-mode values — see the light block. */
  --pw-tint-brand-bg:     rgba(76, 144, 254, 0.16);
  --pw-tint-brand-fg:     var(--pw-color-brand-300);
  --pw-tint-success-bg:   rgba(18, 183, 106, 0.16);
  --pw-tint-success-fg:   var(--pw-color-success-300);
  --pw-tint-warning-bg:   rgba(247, 144, 9, 0.16);
  --pw-tint-warning-fg:   var(--pw-color-warning-400);
  --pw-tint-danger-bg:    rgba(240, 68, 56, 0.16);
  --pw-tint-danger-fg:    var(--pw-color-danger-250);
  --pw-tint-ai-bg:        rgba(122, 90, 248, 0.18);
  --pw-tint-ai-fg:        #c3b5fd;
  --pw-ai-glow-a:         rgba(76, 144, 254, 0.14);
  --pw-ai-glow-b:         rgba(122, 90, 248, 0.20);
  --pw-ai-edge-a:         rgba(108, 164, 254, 0.46);
  --pw-ai-edge-b:         rgba(160, 135, 250, 0.52);
  --pw-ai-mesh-a:         #3cc3e6;
  --pw-ai-mesh-b:         #ec5d4a;
  --pw-ai-mesh-c:         #f4bd57;
  --pw-bg-disabled:       var(--pw-color-gray-900);

  --pw-fg-primary:      var(--pw-color-gray-200);
  --pw-fg-secondary:    var(--pw-color-gray-300);
  --pw-fg-tertiary:     var(--pw-color-gray-400);
  --pw-fg-quaternary:   var(--pw-color-gray-500);
  --pw-fg-disabled:     var(--pw-color-gray-600);
  --pw-fg-inverse:      var(--pw-color-gray-950);
  --pw-fg-brand:        var(--pw-color-brand-400);
  --pw-fg-on-brand:     var(--pw-color-white);
  --pw-bg-on-brand:     rgba(255, 255, 255, 0.22);
  --pw-fg-on-overlay:   var(--pw-color-white);
  --pw-fg-on-artwork:   var(--pw-color-gray-950);
  --pw-fg-link:         var(--pw-color-link-dark);
  --pw-fg-link-visited: var(--pw-color-link-visited-dark);
  --pw-fg-success:      var(--pw-color-success-400);
  --pw-fg-warning:      var(--pw-color-warning-400);
  --pw-fg-danger:       var(--pw-color-danger-350);
  --pw-fg-info:         var(--pw-color-info-500);

  /* Inverted with the ramp: fainter here means nearer the ground, not lighter. */
  --pw-border-faint:   var(--pw-color-gray-850);
  --pw-border-subtle:  var(--pw-color-gray-800);
  --pw-border-default: var(--pw-color-gray-700);
  --pw-border-strong:  var(--pw-color-gray-600);
  --pw-border-inverse: var(--pw-color-gray-100);
  --pw-border-brand:   var(--pw-color-brand-600);
  --pw-border-danger:  var(--pw-color-danger-500);
  --pw-border-success: var(--pw-color-success-500);

  --pw-action-bg:        var(--pw-color-brand-600);
  --pw-action-bg-hover:  var(--pw-color-brand-700);
  --pw-action-bg-active: var(--pw-color-brand-800);
  /* On a dark canvas the link goes the other way: brand-700 would sink into
     the background, so text-only actions lighten instead of darkening. */
  --pw-action-link:        var(--pw-color-brand-400);
  /* Results-header search field: filled at rest, lighter on focus. */
  --pw-serp-search-bg:        var(--pw-bg-surface);
  --pw-serp-search-bg-hover:  var(--pw-bg-surface);
  --pw-serp-search-bg-focus:  var(--pw-bg-surface);
  --pw-serp-search-border:    var(--pw-border-default);
  --pw-serp-search-sheen:     transparent;
  --pw-serp-search-ring:      rgba(255, 255, 255, 0.14);
  /* Translucent overlays for controls that sit on an unknown ground — an
     icon button inside a field, a chip on a photo. A fixed grey works on
     white and turns into a hole the moment the surface behind it is tinted. */
  --pw-ink-hover:  rgba(255, 255, 255, 0.10);
  /* The themed half of the brand mark: the fingerprint ridges and the
     "Privacy" wordmark. The shield's brand colours are fixed and are not
     tokens — they never follow the theme. */
  --pw-logo-ink: var(--pw-color-gray-25);
  --pw-ink-active: rgba(255, 255, 255, 0.16);
  --pw-action-link-hover:  var(--pw-color-brand-300);
  --pw-action-link-active: var(--pw-color-brand-200);
  --pw-action-fg:        var(--pw-color-white);
  --pw-action-border:    transparent;

  --pw-action-2-bg:           var(--pw-color-gray-900);
  --pw-action-2-bg-hover:     var(--pw-color-gray-800);
  --pw-action-2-bg-active:    var(--pw-color-gray-700);
  --pw-action-2-fg:           var(--pw-color-gray-200);
  --pw-action-2-border:       var(--pw-color-gray-700);
  --pw-action-2-border-hover: var(--pw-color-gray-600);

  --pw-action-3-bg-hover:  var(--pw-color-gray-800);
  --pw-action-3-bg-active: var(--pw-color-gray-700);
  --pw-action-3-fg:        var(--pw-color-gray-300);

  --pw-field-bg:           var(--pw-color-gray-900);
  --pw-field-bg-hover:     var(--pw-color-gray-800);
  --pw-field-bg-disabled:  var(--pw-color-gray-900);
  --pw-field-border:       var(--pw-color-gray-700);
  --pw-field-border-hover: var(--pw-color-gray-600);
  --pw-field-border-focus: var(--pw-color-brand-600);
  --pw-field-fg:           var(--pw-color-gray-50);
  --pw-field-placeholder:  var(--pw-color-gray-400);
  --pw-field-icon:         var(--pw-color-gray-400);

  --pw-focus-ring-color: rgba(61, 128, 236, 0.40);
  --pw-focus-ring:       0 0 0 4px var(--pw-focus-ring-color);

  --pw-shadow-drop: drop-shadow(0 8px 12px rgba(0, 0, 0, 0.40)) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.28));
  --pw-shadow-xs:     0 1px 2px 0 rgba(0, 0, 0, 0.30);
  --pw-shadow-sm:     0 1px 3px 0 rgba(0, 0, 0, 0.36), 0 1px 2px 0 rgba(0, 0, 0, 0.24);
  --pw-shadow-md:     0 4px 8px -2px rgba(0, 0, 0, 0.40), 0 2px 4px -2px rgba(0, 0, 0, 0.24);
  --pw-shadow-lg:     0 12px 16px -4px rgba(0, 0, 0, 0.44), 0 4px 6px -2px rgba(0, 0, 0, 0.24);
  --pw-shadow-xl:     0 20px 24px -4px rgba(0, 0, 0, 0.48), 0 8px 8px -4px rgba(0, 0, 0, 0.24);
  --pw-shadow-2xl:    0 24px 48px -12px rgba(0, 0, 0, 0.56);
  --pw-shadow-3xl:    0 32px 64px -12px rgba(0, 0, 0, 0.60);
  --pw-shadow-modal:  0 24px 48px 0 rgba(0, 0, 0, 0.36), 0 10px 22px 0 rgba(0, 0, 0, 0.24);
  --pw-shadow-overlay: 0 1px 2px 0 rgba(0, 0, 0, 0.44), 0 6px 16px -2px rgba(0, 0, 0, 0.40);
  --pw-shadow-map-ui: var(--pw-shadow-overlay);   /* legacy alias */

  --pw-frost-fill:        rgba(255, 255, 255, 0.08);
  --pw-frost-fill-hover:  rgba(255, 255, 255, 0.13);
  --pw-frost-fill-active: rgba(255, 255, 255, 0.18);
  /* No edge in dark. In light the frost border is a near-white hairline that
     reads as the lit edge of a piece of glass; the same construction in dark
     draws an outline instead, because `background` paints under the border box
     and the two translucent whites STACK there — an 8% fill plus a 10% border
     composites to roughly 17% at the rim, which is a visible ring around every
     tile. Dark glass has no lit edge to depict, so it gets none. */
  --pw-frost-border:      transparent;
  /* Far less transparent than the light one. 72% of a near-black over LIGHT map
     tiles composites to a washed grey-green — the panel stops reading as a dark
     surface at all and every dark card on it loses its ground. Frosted glass in
     a dark UI is mostly opaque with a hint of what is behind it; the light
     version can afford 72% because it is tinting toward the tiles rather than
     away from them. */
  /* The map goes dark too. An illustration is not exempt from the theme just
     because it is a picture: a daylight map behind a dark panel is the single
     brightest thing on the screen, it lights the frosted chrome from underneath,
     and every marker on it was picked to read against night tiles. Same
     geometry, night palette — water and the motorway keep their hue rather than
     going grey with everything else, because those are the two things a map has
     to stay findable by. */
  --pw-map-tile: url("../assets/maps/canvas-dark.svg");
  --pw-map-tile-fallback: linear-gradient(150deg, #1e2225, #1a222b 55%, #23211d);

  --pw-rail-surface: rgba(32, 33, 36, 0.92);
  --pw-rail-blur:    blur(18px) saturate(1.4);

  --pw-scrollbar-thumb:       rgba(205, 208, 212, 0.28);
  --pw-scrollbar-thumb-hover: rgba(205, 208, 212, 0.42);

  --pw-skeleton-base:  var(--pw-color-gray-800);
  --pw-skeleton-sheen: var(--pw-color-gray-700);
}

/* Follow the OS when the host app has not stamped an explicit theme class.
   Production PrivacyWall always writes `.light` or `.dark` on <html>; this block
   keeps the system correct for CSS-only consumers that do not.
   `[data-pw-theme="dark"|"light"]` applies a theme to a subtree — use it for a
   dark panel inside a light page, or for side-by-side comparisons. */
@media (prefers-color-scheme: dark) {
  html:not(.light):not(.dark) {
    color-scheme: dark;

    /* The two ramp steps that differ per theme. Everything else is shared. */
    --pw-color-gray-25:  #fafafa;
    /* One step between 800 and 900, so a row separator can sit nearer the ground
     than a surface border does. Dark only: the light ramp has gray-50 already. */
  --pw-color-gray-850: #383a3e;
  --pw-color-gray-900: #2d2f32;

    --pw-bg-canvas:         var(--pw-color-gray-950);
    --pw-bg-canvas-subtle:  var(--pw-color-gray-950);
    --pw-bg-surface:        var(--pw-color-gray-900);
    --pw-bg-surface-raised: var(--pw-color-gray-800);
    --pw-bg-subtle:         var(--pw-color-gray-950);
    --pw-bg-muted:          var(--pw-color-gray-800);
    --pw-bg-strong:         var(--pw-color-gray-700);
    --pw-bg-inverse:        var(--pw-color-gray-50);
    --pw-bg-overlay:        rgba(0, 0, 0, 0.60);
    --pw-bg-lightbox:       rgba(0, 0, 0, 0.72);
    --pw-bg-on-overlay:     rgba(255, 255, 255, 0.16);
    --pw-bg-on-overlay-strong: rgba(255, 255, 255, 0.28);
    --pw-bg-hover:          var(--pw-color-gray-800);
    --pw-bg-hover-on-subtle: var(--pw-color-gray-800);
    --pw-bg-active:         var(--pw-color-gray-700);
    --pw-bg-selected:       rgba(61, 128, 236, 0.20);
    --pw-bg-selected-neutral: var(--pw-color-gray-700);
    /* Tints, inverted. Same pairs, dark-mode values — see the light block. */
    --pw-tint-brand-bg:     rgba(76, 144, 254, 0.16);
    --pw-tint-brand-fg:     var(--pw-color-brand-300);
    --pw-tint-success-bg:   rgba(18, 183, 106, 0.16);
    --pw-tint-success-fg:   var(--pw-color-success-300);
    --pw-tint-warning-bg:   rgba(247, 144, 9, 0.16);
    --pw-tint-warning-fg:   var(--pw-color-warning-400);
    --pw-tint-danger-bg:    rgba(240, 68, 56, 0.16);
    --pw-tint-danger-fg:    var(--pw-color-danger-250);
    --pw-tint-ai-bg:        rgba(122, 90, 248, 0.18);
    --pw-tint-ai-fg:        #c3b5fd;
    --pw-ai-glow-a:         rgba(76, 144, 254, 0.14);
    --pw-ai-glow-b:         rgba(122, 90, 248, 0.20);
    --pw-ai-edge-a:         rgba(108, 164, 254, 0.46);
    --pw-ai-edge-b:         rgba(160, 135, 250, 0.52);
    --pw-ai-mesh-a:         #3cc3e6;
    --pw-ai-mesh-b:         #ec5d4a;
    --pw-ai-mesh-c:         #f4bd57;
    --pw-bg-disabled:       var(--pw-color-gray-900);

    --pw-fg-primary:      var(--pw-color-gray-200);
    --pw-fg-secondary:    var(--pw-color-gray-300);
    --pw-fg-tertiary:     var(--pw-color-gray-400);
    --pw-fg-quaternary:   var(--pw-color-gray-500);
    --pw-fg-disabled:     var(--pw-color-gray-600);
    --pw-fg-inverse:      var(--pw-color-gray-950);
    --pw-fg-brand:        var(--pw-color-brand-400);
    --pw-fg-on-brand:     var(--pw-color-white);
    --pw-bg-on-brand:     rgba(255, 255, 255, 0.22);
    --pw-fg-on-overlay:   var(--pw-color-white);
    --pw-fg-on-artwork:   var(--pw-color-gray-950);
    --pw-fg-link:         var(--pw-color-link-dark);
    --pw-fg-link-visited: var(--pw-color-link-visited-dark);
    --pw-fg-success:      var(--pw-color-success-400);
    --pw-fg-warning:      var(--pw-color-warning-400);
    --pw-fg-danger:       var(--pw-color-danger-350);
    --pw-fg-info:         var(--pw-color-info-500);

    /* Inverted with the ramp: fainter here means nearer the ground, not lighter. */
  --pw-border-faint:   var(--pw-color-gray-850);
  --pw-border-subtle:  var(--pw-color-gray-800);
    --pw-border-default: var(--pw-color-gray-700);
    --pw-border-strong:  var(--pw-color-gray-600);
    --pw-border-inverse: var(--pw-color-gray-100);
    --pw-border-brand:   var(--pw-color-brand-600);
    --pw-border-danger:  var(--pw-color-danger-500);
    --pw-border-success: var(--pw-color-success-500);

    --pw-action-bg:        var(--pw-color-brand-600);
    --pw-action-bg-hover:  var(--pw-color-brand-700);
    --pw-action-bg-active: var(--pw-color-brand-800);
    /* On a dark canvas the link goes the other way: brand-700 would sink into
       the background, so text-only actions lighten instead of darkening. */
    --pw-action-link:        var(--pw-color-brand-400);
    /* Results-header search field: filled at rest, lighter on focus. */
    --pw-serp-search-bg:        var(--pw-bg-surface);
    --pw-serp-search-bg-hover:  var(--pw-bg-surface);
    --pw-serp-search-bg-focus:  var(--pw-bg-surface);
    --pw-serp-search-border:    var(--pw-border-default);
    --pw-serp-search-sheen:     transparent;
    --pw-serp-search-ring:      rgba(255, 255, 255, 0.14);
    /* Translucent overlays for controls that sit on an unknown ground — an
       icon button inside a field, a chip on a photo. A fixed grey works on
       white and turns into a hole the moment the surface behind it is tinted. */
    --pw-ink-hover:  rgba(255, 255, 255, 0.10);
    /* The themed half of the brand mark: the fingerprint ridges and the
       "Privacy" wordmark. The shield's brand colours are fixed and are not
       tokens — they never follow the theme. */
    --pw-logo-ink: var(--pw-color-gray-25);
    --pw-ink-active: rgba(255, 255, 255, 0.16);
    --pw-action-link-hover:  var(--pw-color-brand-300);
    --pw-action-link-active: var(--pw-color-brand-200);
    --pw-action-fg:        var(--pw-color-white);
    --pw-action-border:    transparent;

    --pw-action-2-bg:           var(--pw-color-gray-900);
    --pw-action-2-bg-hover:     var(--pw-color-gray-800);
    --pw-action-2-bg-active:    var(--pw-color-gray-700);
    --pw-action-2-fg:           var(--pw-color-gray-200);
    --pw-action-2-border:       var(--pw-color-gray-700);
    --pw-action-2-border-hover: var(--pw-color-gray-600);

    --pw-action-3-bg-hover:  var(--pw-color-gray-800);
    --pw-action-3-bg-active: var(--pw-color-gray-700);
    --pw-action-3-fg:        var(--pw-color-gray-300);

    --pw-field-bg:           var(--pw-color-gray-900);
    --pw-field-bg-hover:     var(--pw-color-gray-800);
    --pw-field-bg-disabled:  var(--pw-color-gray-900);
    --pw-field-border:       var(--pw-color-gray-700);
    --pw-field-border-hover: var(--pw-color-gray-600);
    --pw-field-border-focus: var(--pw-color-brand-600);
    --pw-field-fg:           var(--pw-color-gray-50);
    --pw-field-placeholder:  var(--pw-color-gray-400);
    --pw-field-icon:         var(--pw-color-gray-400);

    --pw-focus-ring-color: rgba(61, 128, 236, 0.40);
    --pw-focus-ring:       0 0 0 4px var(--pw-focus-ring-color);

    --pw-shadow-drop: drop-shadow(0 8px 12px rgba(0, 0, 0, 0.40)) drop-shadow(0 2px 4px rgba(0, 0, 0, 0.28));
  --pw-shadow-xs:     0 1px 2px 0 rgba(0, 0, 0, 0.30);
    --pw-shadow-sm:     0 1px 3px 0 rgba(0, 0, 0, 0.36), 0 1px 2px 0 rgba(0, 0, 0, 0.24);
    --pw-shadow-md:     0 4px 8px -2px rgba(0, 0, 0, 0.40), 0 2px 4px -2px rgba(0, 0, 0, 0.24);
    --pw-shadow-lg:     0 12px 16px -4px rgba(0, 0, 0, 0.44), 0 4px 6px -2px rgba(0, 0, 0, 0.24);
    --pw-shadow-xl:     0 20px 24px -4px rgba(0, 0, 0, 0.48), 0 8px 8px -4px rgba(0, 0, 0, 0.24);
    --pw-shadow-2xl:    0 24px 48px -12px rgba(0, 0, 0, 0.56);
    --pw-shadow-3xl:    0 32px 64px -12px rgba(0, 0, 0, 0.60);
    --pw-shadow-modal:  0 24px 48px 0 rgba(0, 0, 0, 0.36), 0 10px 22px 0 rgba(0, 0, 0, 0.24);
    --pw-shadow-overlay: 0 1px 2px 0 rgba(0, 0, 0, 0.44), 0 6px 16px -2px rgba(0, 0, 0, 0.40);
    --pw-shadow-map-ui: var(--pw-shadow-overlay);   /* legacy alias */

    --pw-frost-fill:        rgba(255, 255, 255, 0.08);
    --pw-frost-fill-hover:  rgba(255, 255, 255, 0.13);
    --pw-frost-fill-active: rgba(255, 255, 255, 0.18);
    --pw-frost-border:      transparent;
    --pw-map-tile: url("../assets/maps/canvas-dark.svg");
    --pw-map-tile-fallback: linear-gradient(150deg, #1e2225, #1a222b 55%, #23211d);

    --pw-rail-surface: rgba(32, 33, 36, 0.92);
    --pw-rail-blur:    blur(18px) saturate(1.4);

    --pw-scrollbar-thumb:       rgba(205, 208, 212, 0.28);
    --pw-scrollbar-thumb-hover: rgba(205, 208, 212, 0.42);

    --pw-skeleton-base:  var(--pw-color-gray-800);
    --pw-skeleton-sheen: var(--pw-color-gray-700);
  }
}


/* =============================================================================
   SITE WASHES
   The soft two-colour grounds a marketing page lays behind a section, a panel
   or a card. They are ARTWORK-adjacent: a wash is tint, not surface, so it sits
   behind content and never carries a hairline. Light washes are pale
   (blue into warm, mint or cream); dark ones start at the same slate and warm
   towards brown, green or blue, so every wash reads as the same family in both
   themes. Used through .pw-wash-* in pw-site.css.
   ============================================================================= */
:root {
  --pw-wash-warm:     linear-gradient(180deg, #eff3f7 0%, #fef3ec 100%);
  --pw-wash-lavender: linear-gradient(180deg, #f3f1ff 0%, #e9efff 100%);
  --pw-wash-cream:    linear-gradient(180deg, #fef8ee 0%, #f0e7dd 100%);
  --pw-wash-mint:     linear-gradient(180deg, #eef5fe 0%, #ddf0e2 100%);
  --pw-wash-feature-1: linear-gradient(160deg, #eef5fe, #f9fbe9);
  --pw-wash-feature-2: linear-gradient(145deg, #eef5fe, #daffd7);
  --pw-wash-feature-3: linear-gradient(145deg, #eef5fe, #f3ede5);
  --pw-wash-feature-4: linear-gradient(180deg, #eef5fe, #fff4e1);
  --pw-wash-feature-5: linear-gradient(180deg, #eef5fe, #e3eeff);
}
html.dark {
  --pw-wash-warm:     linear-gradient(180deg, #29323c 0%, #3d312a 100%);
  --pw-wash-lavender: linear-gradient(146deg, #29323c 20%, #3d312a 92%);
  --pw-wash-cream:    linear-gradient(180deg, #3f3b34 0%, #372f27 100%);
  --pw-wash-mint:     linear-gradient(180deg, #2f343a 0%, #28322a 100%);
  --pw-wash-feature-1: linear-gradient(160deg, #29333c, #37382d);
  --pw-wash-feature-2: linear-gradient(145deg, #29333c, #40523e);
  --pw-wash-feature-3: linear-gradient(145deg, #29333c, #39342d);
  --pw-wash-feature-4: linear-gradient(180deg, #29333c, #3e382d);
  --pw-wash-feature-5: linear-gradient(180deg, #29333c, #30364a);
}
@media (prefers-color-scheme: dark) {
  html:not(.light):not(.dark) {
    --pw-wash-warm:     linear-gradient(180deg, #29323c 0%, #3d312a 100%);
    --pw-wash-lavender: linear-gradient(146deg, #29323c 20%, #3d312a 92%);
    --pw-wash-cream:    linear-gradient(180deg, #3f3b34 0%, #372f27 100%);
    --pw-wash-mint:     linear-gradient(180deg, #2f343a 0%, #28322a 100%);
    --pw-wash-feature-1: linear-gradient(160deg, #29333c, #37382d);
    --pw-wash-feature-2: linear-gradient(145deg, #29333c, #40523e);
    --pw-wash-feature-3: linear-gradient(145deg, #29333c, #39342d);
    --pw-wash-feature-4: linear-gradient(180deg, #29333c, #3e382d);
    --pw-wash-feature-5: linear-gradient(180deg, #29333c, #30364a);
  }
}
