/* Shared look for every page (listings, dashboard, legal, admin): tokens, the navy and light themes, the theme
   switch, buttons, the price sticker and the few motions that report a change of state.
   Served at /assets/theme.css by the monitor and the Worker. theme.js sets data-theme before paint.

   The idea (the owner's reference picture, 2026-10-11): a navy night with a soft glow behind the content, and
   the things that matter drawn in chunky pastel. Two gradients, each with one job: cool mint -> periwinkle is
   action and identity (the main button, the logo, the current section); warm butter -> pink -> lilac is money
   (the price stickers). Fredoka, rounded and heavy, for headings, the name and prices; Bricolage for reading.
   State colours stay plain and only mean something: green good news, red a problem, blue links and focus.
   Navy is the default; data-theme="light" is the lavender-white version with the same gradients. */

@font-face {
  font-family: "Bricolage Grotesque";
  src: url("/assets/bricolage.woff2?v=5") format("woff2"); /* versioned: the file is cached for a year */
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Fredoka";
  src: url("/assets/fredoka.woff2?v=1") format("woff2"); /* SIL OFL: Fredoka-OFL.txt */
  font-weight: 300 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* navy, the default (every text colour 4.5:1+ on every surface, the glow included; ink on the gradients 7:1+).
     Cards have no outline here: the lighter fill and the soft shadow lift them, as in the reference. */
  --bg: #2e4581; --panel: #314889; --card: #374f91; --fg: #f4f6ff; --muted: #d3d9f3;
  --soft: #334a8b; --hover: #41599c; --line: #4b62a3; --line-strong: #6379b8;
  --glow: #425a88; --mark: #1f2d5c; --card-edge: transparent; --card-edge-hover: transparent;
  --price: #ffe9a3; --price-fg: #1f2b55; --ink-on-pastel: #1f2b55;
  --grad-cool: linear-gradient(100deg, #c4f7dc, #a6bfff);
  --grad-warm: linear-gradient(100deg, #fff0a3, #ffbfd8 55%, #f5b0fc);
  --grad-text: linear-gradient(100deg, #c4f7dc, #a6bfff 48%, #ffbfd8 80%, #fff0a3);
  --grad-name: var(--grad-cool);
  --link: #cfdbff; --focus: #d6c4ff;
  --good: #a3f5c9; --good-soft: rgba(163, 245, 201, .07); --good-line: rgba(163, 245, 201, .55); --bad: #ffcad2; --warn: #ffe09a;
  --scrim: rgba(10, 15, 38, .62);
  --lift: drop-shadow(0 4px 8px rgba(8, 13, 36, .45));
  --shadow-card: 0 1px 2px rgba(8, 13, 36, .22), 0 10px 24px -14px rgba(8, 13, 36, .7);
  --shadow-pop: 0 2px 4px rgba(8, 13, 36, .28), 0 16px 32px -12px rgba(8, 13, 36, .7);
  --shadow-sticker: 0 2px 0 rgba(8, 13, 36, .18), 0 6px 14px -6px rgba(8, 13, 36, .55);
  color-scheme: dark;
}
:root[data-theme="light"] {
  /* every text colour 4.5:1+ on every surface; the headings. deeper gradient stops 4.2:1+ (large text) */
  --bg: #f2f1fb; --panel: #f8f7fd; --card: #ffffff; --fg: #22305a; --muted: #555e87;
  --soft: #ecebf7; --hover: #e8e6f6; --line: #dfdcef; --line-strong: #c4c0de;
  --glow: #e4ebff; --mark: #2e4581; --card-edge: var(--line); --card-edge-hover: var(--line-strong);
  --price: #ffe48a; --price-fg: #1f2b55; --ink-on-pastel: #1f2b55;
  --grad-cool: linear-gradient(100deg, #b6f1d2, #9fb7ff);
  --grad-warm: linear-gradient(100deg, #ffec8f, #ffb6d4 55%, #f2a6fa);
  --grad-text: linear-gradient(100deg, #127d5a, #3f5bd8 50%, #b0338f);
  --grad-name: linear-gradient(100deg, #127d5a, #3f5bd8);
  --link: #3a4fc4; --focus: #5b46d6;
  --good: #13774a; --good-soft: rgba(19, 119, 74, .1); --good-line: transparent; --bad: #c0304a; --warn: #8f5a00;
  --scrim: rgba(24, 30, 60, .45);
  --lift: drop-shadow(0 3px 6px rgba(38, 54, 95, .18));
  --shadow-card: 0 1px 2px rgba(38, 54, 95, .06), 0 10px 24px -14px rgba(38, 54, 95, .3);
  --shadow-pop: 0 2px 4px rgba(38, 54, 95, .08), 0 16px 32px -12px rgba(38, 54, 95, .32);
  --shadow-sticker: 0 2px 0 rgba(38, 54, 95, .08), 0 6px 14px -6px rgba(38, 54, 95, .35);
  color-scheme: light;
}
:root {
  /* The main action is the cool gradient with navy ink, in either theme. Older names stay as aliases. */
  --primary: var(--fg); --primary-fg: var(--card); --primary-soft: var(--soft); --primary-text: var(--fg);
  --glass: var(--card); --glass-solid: var(--card);
  --shadow-sm: none; --shadow: var(--shadow-card); --shadow-lg: var(--shadow-pop);
  /* type scale (product UI, ~1.15 steps, nothing under 13 px) */
  --fs-xs: 13px; --fs-sm: 14px; --fs-md: 15px; --fs-lg: 17px; --fs-xl: 20px; --fs-2xl: 28px;
  --r: 16px; --r-sm: 10px;
  --ease-out: cubic-bezier(.22, 1, .36, 1); --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --spring: var(--ease-out); /* kept for old references: nothing overshoots */
  --sans: "Bricolage Grotesque", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --display: "Fredoka", "Bricolage Grotesque", ui-rounded, ui-sans-serif, system-ui, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { background: var(--bg); scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; -webkit-text-size-adjust: 100%; }
/* The soft glow of the reference: a lighter pool of navy (lavender on light) behind the top of the page. */
body {
  margin: 0; color: var(--fg); font: 400 var(--fs-md)/1.5 var(--sans);
  background: radial-gradient(ellipse 75% 60% at 50% 14%, var(--glow), transparent 78%) fixed, var(--bg);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "cv11", "ss01";
}
::selection { background: var(--price); color: var(--price-fg); }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 10px; border: 3px solid var(--bg); }
a { color: inherit; text-underline-offset: 3px; text-decoration-thickness: 1px; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
button, input, select, textarea { font: inherit; color: inherit; }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }
input, select, textarea { caret-color: var(--focus); accent-color: var(--link); }
.num, .tnum { font-variant-numeric: tabular-nums; }

/* ---------- display type: chunky and rounded; the page title in the pastel gradient ---------- */
h1, h2, .display { font-family: var(--display); letter-spacing: 0; }
h1 { font-weight: 650; width: fit-content; max-width: 100%; filter: var(--lift); } /* lifted off the ground like the reference letters */
h2 { font-weight: 600; }
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  h1 { background: var(--grad-text); -webkit-background-clip: text; background-clip: text; color: transparent; -webkit-text-fill-color: transparent; }
  h1::selection { -webkit-text-fill-color: var(--price-fg); }
}
@media (forced-colors: active) { h1 { background: none; color: CanvasText; -webkit-text-fill-color: CanvasText; } }

/* ---------- logo: a chunky crosshair on a navy tile, tilted like a sticker; the name in the cool gradient ---------- */
.logo {
  display: inline-flex; align-items: center; gap: 10px; font: 700 21px/1.1 var(--display); text-decoration: none; color: var(--fg);
  background: var(--grad-name); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; filter: var(--lift);
}
@media (forced-colors: active) { .logo { -webkit-text-fill-color: LinkText; background: none; } }
.logo-mark {
  width: 32px; height: 32px; border-radius: 10px; display: grid; place-items: center; flex: none; background: var(--mark);
  transform: rotate(-8deg);
}
.logo-mark svg { display: none; }
.logo-mark::before {
  content: ""; width: 23px; height: 23px; background: linear-gradient(120deg, #c4f7dc, #a6bfff 55%, #f5b0fc);
  -webkit-mask: var(--crosshair) center / contain no-repeat; mask: var(--crosshair) center / contain no-repeat;
}
:root { --crosshair: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3.6' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='6.6'/%3E%3Ccircle cx='12' cy='12' r='2.4' fill='%23000' stroke='none'/%3E%3Cpath d='M12 2v3M12 19v3M2 12h3M19 12h3'/%3E%3C/svg%3E"); }

/* ---------- buttons: pills; the main one is the cool gradient ---------- */
.btn {
  --b: var(--line-strong); display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 36px; padding: 7px 16px; border-radius: 999px; border: 1px solid var(--b); background: var(--card);
  color: var(--fg); font: 600 var(--fs-sm)/1.2 var(--sans); text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background-color .15s var(--ease-out), border-color .15s var(--ease-out), color .15s var(--ease-out),
    box-shadow .2s var(--ease-out), transform .2s var(--ease-out), filter .2s var(--ease-out);
}
.btn:hover:not(:disabled):not([disabled]) { --b: var(--fg); background: var(--hover); }
.btn:active:not(:disabled):not([disabled]) { background: var(--soft); transform: translateY(1px); }
.btn.primary, .btn.accent { background: var(--grad-cool); color: var(--ink-on-pastel); --b: transparent; box-shadow: var(--shadow-sticker); }
.btn.primary:hover:not(:disabled):not([disabled]), .btn.accent:hover:not(:disabled):not([disabled]) {
  background: var(--grad-cool); --b: transparent; filter: saturate(1.25) brightness(1.04); transform: translateY(-1px);
}
.btn.ghost { background: transparent; }
.btn.danger { background: transparent; color: var(--bad); }
.btn.danger:hover:not(:disabled):not([disabled]) { --b: var(--bad); }
.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn .arr { display: inline-block; }

/* ---------- the price sticker: the warm gradient, navy figures, slightly tilted ---------- */
.price-label {
  display: inline-block; padding: 4px 10px 3px; border-radius: 10px; background: var(--grad-warm); color: var(--price-fg);
  font: 650 1em/1.15 var(--display); font-variant-numeric: tabular-nums; transform: rotate(-2deg); box-shadow: var(--shadow-sticker);
}

/* ---------- theme switch (sun / moon) ---------- */
.theme-switch {
  position: relative; width: 46px; height: 26px; flex: none; padding: 0; border: 1px solid var(--line-strong); border-radius: 999px;
  background: var(--soft); cursor: pointer; transition: background-color .2s var(--ease-out), border-color .2s var(--ease-out);
}
.theme-switch:hover { border-color: var(--fg); }
.theme-switch .knob {
  position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: var(--card);
  box-shadow: 0 1px 3px rgba(8, 13, 36, .35); display: grid; place-items: center; color: var(--fg);
  transition: transform .25s var(--ease-out);
}
.theme-switch svg { width: 12px; height: 12px; grid-area: 1 / 1; transition: opacity .2s; }
.theme-switch .moon { opacity: 0; }
.theme-switch[aria-checked="true"] { background: var(--grad-cool); border-color: transparent; }
.theme-switch[aria-checked="true"] .knob { transform: translateX(20px); background: var(--ink-on-pastel); color: #c4f7dc; }
.theme-switch[aria-checked="true"] .sun { opacity: 0; }
.theme-switch[aria-checked="true"] .moon { opacity: 1; }

/* The one authored moment: the new theme grows as a circle from the switch (View Transitions). */
@property --reveal-radius { syntax: "<length-percentage>"; inherits: false; initial-value: 0px; }
@keyframes reveal-in { from { --reveal-radius: 0px; } to { --reveal-radius: 150vmax; } }
::view-transition-old(root) { animation: none; mix-blend-mode: normal; }
::view-transition-new(root) {
  mix-blend-mode: normal; animation: .45s var(--ease-in-out) forwards reveal-in;
  -webkit-mask-image: radial-gradient(circle at var(--x, 50%) var(--y, 0%), #000 calc(var(--reveal-radius) - 40px), transparent calc(var(--reveal-radius) + 40px));
  mask-image: radial-gradient(circle at var(--x, 50%) var(--y, 0%), #000 calc(var(--reveal-radius) - 40px), transparent calc(var(--reveal-radius) + 40px));
}
::view-transition-image-pair(root) { isolation: isolate; }

/* ---------- status dot: still; its colour is the state ---------- */
.live-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: none; }
.live-dot.live { background: var(--good); }

/* ---------- motion: only for a change of state ---------- */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }
@keyframes arrive { from { opacity: 0; transform: translateY(-6px); } }
@keyframes pop { 50% { transform: scale(1.18); } }
.spinner { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--line-strong); border-top-color: var(--link); animation: spin .9s linear infinite; flex: none; }

/* ---------- dialogs ---------- */
dialog { border: 1px solid var(--card-edge); border-radius: var(--r); background: var(--card); color: var(--fg); box-shadow: var(--shadow-pop); }
dialog[open] { animation: rise .2s var(--ease-out); }
dialog::backdrop { background: var(--scrim); animation: fade .2s var(--ease-out); }

@media print {
  html, body { background: #fff; color: #000; }
  h1, .logo { background: none; color: #000; -webkit-text-fill-color: #000; filter: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; animation-delay: 0ms !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
  ::view-transition-new(root) { animation: none; -webkit-mask-image: none; mask-image: none; }
}
