/* Callover design tokens and base recipes.
   Spec: docs/DESIGN.md. Two identical copies live at site/css/tokens.css and app/public/css/tokens.css;
   edit one, copy to the other. Plain CSS, no build step. Fonts come from Google Fonts only. */

@import url("https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600&family=Schibsted+Grotesk:ital,wght@0,600;1,600&display=swap");

/* ------------------------------------------------------------------
   1. Tokens. Light is the default scheme.
   ------------------------------------------------------------------ */
:root{
  color-scheme:light;

  /* surfaces and ink */
  --ground:#F3F2ED;
  --surface:#F9F8F5;
  --raised:#FDFCFA;
  --ink:#16171C;
  --muted:#5A5E6B;

  /* the one accent, cobalt, locked across the whole product */
  --accent:#2A4FD0;
  --accent-ink:#F9F8F5;
  --accent-tint:#E4E7F5;

  /* semantic: the colour is a mark, the word is always there too */
  --success:#1C7448; --success-ink:#155C39; --success-tint:#E2ECE5;
  --warning:#8A5316; --warning-ink:#6B3F0E; --warning-tint:#EFE8DF;
  --danger:#BC382C;  --danger-ink:#8F2A21;  --danger-tint:#F5E4E1;
  --muted-tint:#E9E9E9;

  /* lines, fields, focus */
  --hairline:#E0DED8;
  --hairline-strong:#838792;
  --input-bg:#F3F2ED;
  --focus-ring:0 0 0 3px rgba(42,79,208,.35);
  --nav-bg:rgba(253,252,250,.84);
  --scrim:rgba(22,23,28,.60);

  /* shadows, tinted with the ink's blue-black, never neutral black */
  --shadow-sm:0 1px 2px rgba(20,28,64,.05), 0 2px 6px rgba(20,28,64,.04);
  --shadow-md:0 1px 2px rgba(20,28,64,.04), 0 10px 24px -8px rgba(20,28,64,.10), 0 28px 56px -20px rgba(20,28,64,.12);
  --shadow-lg:0 2px 6px rgba(20,28,64,.04), 0 24px 48px -16px rgba(20,28,64,.14), 0 48px 96px -32px rgba(20,28,64,.16);
  --shadow-frame:0 2px 6px rgba(20,28,64,.04), 0 24px 48px -16px rgba(20,28,64,.14), 0 72px 128px -32px rgba(42,79,208,.20);
  --inset-hi:inset 0 1px 0 rgba(255,255,255,.75);

  /* photographs */
  --photo-filter:saturate(.82) contrast(1.04);
  --grain-opacity:.28;

  /* radius: one system, concentric bezels */
  --r-xs:6px; --r-sm:10px; --r-md:16px; --r-lg:24px; --r-xl:32px; --r-pill:999px;

  /* spacing, base 4 */
  --s-1:4px; --s-2:8px; --s-3:12px; --s-4:16px; --s-5:24px; --s-6:32px; --s-7:48px; --s-8:64px; --s-9:96px; --s-10:128px; --s-11:160px;
  --gutter:clamp(20px, 4vw, 32px);
  --container:1160px;
  --section-y:clamp(96px, 10vw, 160px);
  --nav-h:56px;

  /* type */
  --font-display:'Schibsted Grotesk', 'Geist', system-ui, sans-serif;
  --font-text:'Geist', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --t-display:clamp(2.125rem, 1.25rem + 2.5vw, 3.5rem);
  --t-headline:clamp(1.75rem, 1.1rem + 1.8vw, 2.75rem);
  --t-heading:clamp(1.375rem, 1.2rem + .6vw, 1.75rem);
  --t-title:clamp(1.125rem, 1.05rem + .3vw, 1.3125rem);
  --t-lead:clamp(1.0625rem, 1rem + .3vw, 1.25rem);
  --t-body:1rem;
  --t-small:.8125rem;
  --t-eyebrow:.75rem;

  /* motion */
  --ease:cubic-bezier(.16, 1, .3, 1);
  --ease-inout:cubic-bezier(.45, 0, .55, 1);
  --dur-1:120ms;
  --dur-2:220ms;
  --dur-3:500ms;
}

/* Dark by system preference, unless the visitor chose light */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --ground:#101114;
    --surface:#17181D;
    --raised:#1E1F25;
    --ink:#ECEBE6;
    --muted:#9A9DA9;
    --accent:#8FA4EE;
    --accent-ink:#101114;
    --accent-tint:#303445;
    --success:#5CC48C; --success-ink:#5CC48C; --success-tint:#283935;
    --warning:#E3A64A; --warning-ink:#E3A64A; --warning-tint:#3E352B;
    --danger:#F07A6E;  --danger-ink:#F07A6E;  --danger-tint:#402E31;
    --muted-tint:#32333A;
    --hairline:#2A2B33;
    --hairline-strong:#6E727E;
    --input-bg:#101114;
    --focus-ring:0 0 0 3px rgba(143,164,238,.40);
    --nav-bg:rgba(30,31,37,.84);
    --scrim:rgba(4,6,18,.68);
    --shadow-sm:0 1px 2px rgba(4,6,18,.40), 0 2px 6px rgba(4,6,18,.30);
    --shadow-md:0 1px 2px rgba(4,6,18,.35), 0 10px 24px -8px rgba(4,6,18,.50), 0 28px 56px -20px rgba(4,6,18,.55);
    --shadow-lg:0 2px 6px rgba(4,6,18,.40), 0 24px 48px -16px rgba(4,6,18,.60), 0 48px 96px -32px rgba(4,6,18,.60);
    --shadow-frame:0 2px 6px rgba(4,6,18,.40), 0 24px 48px -16px rgba(4,6,18,.60), 0 72px 128px -32px rgba(143,164,238,.16);
    --inset-hi:inset 0 1px 0 rgba(255,255,255,.06);
    --photo-filter:saturate(.80) contrast(1.05) brightness(.90);
    --grain-opacity:.22;
  }
}

/* Dark by choice: the toggle wins in both directions */
:root[data-theme="dark"]{
  color-scheme:dark;
  --ground:#101114;
  --surface:#17181D;
  --raised:#1E1F25;
  --ink:#ECEBE6;
  --muted:#9A9DA9;
  --accent:#8FA4EE;
  --accent-ink:#101114;
  --accent-tint:#303445;
  --success:#5CC48C; --success-ink:#5CC48C; --success-tint:#283935;
  --warning:#E3A64A; --warning-ink:#E3A64A; --warning-tint:#3E352B;
  --danger:#F07A6E;  --danger-ink:#F07A6E;  --danger-tint:#402E31;
  --muted-tint:#32333A;
  --hairline:#2A2B33;
  --hairline-strong:#6E727E;
  --input-bg:#101114;
  --focus-ring:0 0 0 3px rgba(143,164,238,.40);
  --nav-bg:rgba(30,31,37,.84);
  --scrim:rgba(4,6,18,.68);
  --shadow-sm:0 1px 2px rgba(4,6,18,.40), 0 2px 6px rgba(4,6,18,.30);
  --shadow-md:0 1px 2px rgba(4,6,18,.35), 0 10px 24px -8px rgba(4,6,18,.50), 0 28px 56px -20px rgba(4,6,18,.55);
  --shadow-lg:0 2px 6px rgba(4,6,18,.40), 0 24px 48px -16px rgba(4,6,18,.60), 0 48px 96px -32px rgba(4,6,18,.60);
  --shadow-frame:0 2px 6px rgba(4,6,18,.40), 0 24px 48px -16px rgba(4,6,18,.60), 0 72px 128px -32px rgba(143,164,238,.16);
  --inset-hi:inset 0 1px 0 rgba(255,255,255,.06);
  --photo-filter:saturate(.80) contrast(1.05) brightness(.90);
  --grain-opacity:.22;
}

/* ------------------------------------------------------------------
   2. Base
   ------------------------------------------------------------------ */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%; text-size-adjust:100%}
body{
  margin:0; background:var(--ground); color:var(--ink);
  font:400 var(--t-body)/1.55 var(--font-text);
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
}
h1,h2,h3,h4,p,figure,ul,ol,dl,dd,fieldset{margin:0}
fieldset{padding:0; border:0; min-width:0}
legend{padding:0}
ul[role="list"],ol[role="list"]{list-style:none; padding:0}
img,svg,video,iframe{display:block; max-width:100%}
button,input,select,textarea{font:inherit; color:inherit}
button{cursor:pointer}
a{color:var(--accent)}
[hidden]{display:none !important}
.num{font-variant-numeric:tabular-nums}
.muted{color:var(--muted)}
.sr-only{position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0}

/* layout */
.wrap{max-width:calc(var(--container) + 2 * var(--gutter)); margin:0 auto; padding:0 var(--gutter)}
.section{padding:var(--section-y) 0}

/* ------------------------------------------------------------------
   3. Type scale
   ------------------------------------------------------------------ */
.t-display{font:600 var(--t-display)/1.04 var(--font-display); letter-spacing:-.03em}
.t-headline{font:600 var(--t-headline)/1.08 var(--font-display); letter-spacing:-.025em}
.t-heading{font:600 var(--t-heading)/1.2 var(--font-display); letter-spacing:-.015em}
.t-title{font:600 var(--t-title)/1.3 var(--font-text); letter-spacing:-.01em}
.t-lead{font:400 var(--t-lead)/1.5 var(--font-text)}
.t-body{font:400 var(--t-body)/1.55 var(--font-text)}
.t-small{font:400 var(--t-small)/1.4 var(--font-text); letter-spacing:.01em}
.t-label{font:500 var(--t-small)/1.4 var(--font-text); letter-spacing:.01em}
.t-eyebrow{font:500 var(--t-eyebrow)/1.4 var(--font-text); letter-spacing:.08em; text-transform:uppercase; color:var(--muted)}
.t-display em,.t-headline em,.t-heading em{font-style:italic; font-weight:600}

/* ------------------------------------------------------------------
   4. Buttons: pills with a trailing icon in its own circle
   ------------------------------------------------------------------ */
.btn{
  display:inline-flex; align-items:center; gap:14px;
  height:48px; padding:0 6px 0 22px; border-radius:var(--r-pill);
  border:1px solid transparent; background:var(--raised); color:var(--ink);
  font:500 15px/1 var(--font-text); text-decoration:none; white-space:nowrap; cursor:pointer;
  transition:transform var(--dur-1) var(--ease), background-color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}
.btn .ic{
  width:36px; height:36px; border-radius:50%; display:grid; place-items:center; flex:none;
  transition:transform var(--dur-2) var(--ease), background-color var(--dur-2) var(--ease);
}
.btn .ic svg{width:18px; height:18px}
.btn:hover .ic{transform:translateX(3px)}
.btn:active{transform:scale(.97)}
.btn-primary{background:var(--accent); color:var(--accent-ink)}
.btn-primary .ic{background:var(--accent-ink); color:var(--accent)}
.btn-secondary{border-color:var(--hairline); box-shadow:var(--shadow-sm)}
.btn-secondary .ic{background:var(--ground); color:var(--ink)}
.btn-ghost{background:transparent}
.btn-ghost .ic{background:var(--muted-tint); color:var(--ink)}
.btn-ghost:hover{background:var(--muted-tint)}
/* the one destructive button: a dialog's right-hand action, never a toolbar */
.btn-danger{background:var(--danger); color:var(--accent-ink)}
.btn-danger .ic{background:var(--accent-ink); color:var(--danger)}
.btn-sm{height:40px; padding:0 5px 0 16px; font-size:14px; gap:12px}
.btn-sm .ic{width:30px; height:30px}
.btn-sm .ic svg{width:16px; height:16px}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.5; pointer-events:none}
.btn:focus-visible{outline:none; border-color:var(--accent); box-shadow:var(--focus-ring)}

/* ------------------------------------------------------------------
   5. Cards: the double bezel
   ------------------------------------------------------------------ */
.shell{background:var(--surface); border:1px solid var(--hairline); border-radius:var(--r-lg); padding:8px; box-shadow:var(--shadow-md)}
.core{background:var(--raised); border-radius:var(--r-md); box-shadow:var(--inset-hi); padding:24px}
.shell-compact{border-radius:var(--r-md); padding:6px}
.shell-compact > .core{border-radius:var(--r-sm); padding:16px}
.core-flush{padding:0; overflow:hidden}
/* a flush core is flush inside a compact shell too: the line above is two classes and outweighs
   .core-flush on its own, so a ledger would stop 16px short of its own bezel (DESIGN 10.10) */
.shell-compact > .core.core-flush{padding:0}

/* hover lift: transform on the shell, the deeper shadow faded on a pseudo-element, box-shadow itself never transitions */
.shell-lift{position:relative; isolation:isolate; transition:transform .35s var(--ease)}
.shell-lift::after{
  content:""; position:absolute; inset:-1px; border-radius:inherit; z-index:-1; pointer-events:none;
  box-shadow:var(--shadow-lg); opacity:0; transition:opacity .35s var(--ease);
}
.shell-lift:hover{transform:translateY(-2px)}
.shell-lift:hover::after{opacity:1}

/* the device frame: a bezel and a window, nothing drawn on it */
.stage{position:relative}
.stage-shadow{position:absolute; inset:0; border-radius:var(--r-xl); box-shadow:var(--shadow-frame); pointer-events:none}
.frame{position:relative; background:var(--raised); border:1px solid var(--hairline); border-radius:var(--r-xl); padding:8px; box-shadow:var(--inset-hi)}
.frame .screen{
  position:relative; background:var(--ground); border-radius:var(--r-lg); overflow:hidden;
  aspect-ratio:4/3; max-height:calc(100svh - 300px);
  box-shadow:inset 0 0 0 1px var(--hairline);
}
.frame .screen > iframe{position:absolute; inset:0; width:100%; height:100%; border:0; background:var(--ground)}
@media (max-width:1023px){ .frame .screen{aspect-ratio:16/10; max-height:none} }
@media (max-width:719px){
  .stage{width:100%; max-width:360px; margin-left:auto; margin-right:auto}
  .frame .screen{aspect-ratio:4/5; max-height:calc(100svh - 96px)}
}

/* class card */
.card-class > .core{display:flex; flex-direction:column; gap:8px; height:100%; padding-top:22px}
.card-class h3{font:600 var(--t-title)/1.3 var(--font-text); letter-spacing:-.01em}
.card-class .meta{color:var(--muted); font-size:15px}
.card-foot{
  display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap;
  margin-top:auto; padding-top:16px; border-top:1px solid var(--hairline);
}
.price{font:600 20px/1 var(--font-display); letter-spacing:-.02em; font-variant-numeric:tabular-nums; white-space:nowrap}
.price small{font:500 var(--t-small)/1 var(--font-text); color:var(--muted); letter-spacing:.01em; margin-left:6px}

/* places line: a fact, never a number, never a countdown */
.places{display:flex; align-items:center; gap:8px; font:500 var(--t-body)/1.4 var(--font-text); color:var(--ink)}
.places .dot{
  width:8px; height:8px; border-radius:50%; flex:none;
  background:var(--success); box-shadow:0 0 0 3px var(--success-tint);
  transition:transform var(--dur-3) var(--ease);
}
.places .txt{transition:opacity var(--dur-3) var(--ease)}
.places.is-full{color:var(--muted)}
.places.is-full .dot{background:transparent; border:1.5px solid var(--muted); box-shadow:none}
.places.is-pending .dot{transform:scale(.4)}
.places.is-pending .txt{opacity:0}

/* bento */
.bento{display:grid; gap:16px; grid-auto-flow:dense; grid-template-columns:1fr}
@media (min-width:768px){
  .bento{grid-template-columns:repeat(6, 1fr)}
  .bento > .span-2{grid-column:span 2}
  .bento > .span-3{grid-column:span 3}
  .bento > .span-4{grid-column:span 4}
  .bento > .span-6{grid-column:span 6}
  .bento > .rows-2{grid-row:span 2}
}
.bento > .shell > .core{height:100%}
.cell-photo > .core{padding:0; overflow:hidden; display:flex; flex-direction:column}
.cell-photo .photo{flex:1 1 auto; min-height:200px}
.cell-copy{padding:18px 24px 20px}
.cell-copy h3{font:600 var(--t-title)/1.3 var(--font-text); letter-spacing:-.01em}
.cell-copy p{color:var(--muted); margin-top:4px}
.cell-tint > .core{background:var(--accent-tint); display:flex; flex-direction:column; gap:20px; padding:28px}
.cell-tint .cell-copy{padding:0; margin-top:auto}
.cell-tint h3{font:600 var(--t-heading)/1.2 var(--font-display); letter-spacing:-.015em}

/* confirmation card */
.confirm > .core{display:grid; gap:20px}
.confirm h2{font:600 var(--t-heading)/1.2 var(--font-display); letter-spacing:-.015em}
.summary{display:grid; grid-template-columns:auto 1fr; gap:8px 20px; padding:16px 0; border-top:1px solid var(--hairline); border-bottom:1px solid var(--hairline)}
.summary dt{color:var(--muted); font:500 var(--t-small)/1.5 var(--font-text); letter-spacing:.01em; padding-top:1px}
.summary dd{margin:0}
.confirm .figure{font:600 var(--t-heading)/1.1 var(--font-display); letter-spacing:-.02em; font-variant-numeric:tabular-nums}
.confirm .note{color:var(--muted); font-size:var(--t-small); line-height:1.5}
.confirm .actions{display:flex; flex-wrap:wrap; gap:12px; align-items:center}

/* ------------------------------------------------------------------
   6. Fields
   ------------------------------------------------------------------ */
.field{display:flex; flex-direction:column; gap:8px}
.field > label,.label{font:500 var(--t-small)/1.4 var(--font-text); letter-spacing:.01em; color:var(--ink)}
.input{
  width:100%; height:48px; padding:0 14px; border-radius:var(--r-sm);
  background:var(--input-bg); border:1px solid var(--hairline-strong); color:var(--ink);
  font:400 16px/1 var(--font-text);
  transition:border-color var(--dur-2) var(--ease);
}
textarea.input{height:auto; min-height:120px; padding:12px 14px; line-height:1.5; resize:vertical}
select.input{padding-right:40px; appearance:none; -webkit-appearance:none}
.input::placeholder{color:var(--muted); opacity:1}
.input:focus-visible{outline:none; border-color:var(--accent); box-shadow:var(--focus-ring)}
.input[aria-invalid="true"],.field.is-error .input{border-color:var(--danger)}
.field .help{margin-top:-2px; color:var(--muted); font-size:var(--t-small); line-height:1.45}
.field.is-error .help{color:var(--danger-ink)}

/* checkbox and radio: a real input, styled, with a real ring */
.check{display:flex; gap:12px; align-items:flex-start; cursor:pointer; line-height:1.5}
.check .box{position:relative; width:20px; height:20px; flex:none; margin-top:3px}
.check .box input{
  appearance:none; -webkit-appearance:none; width:20px; height:20px; margin:0; display:block; cursor:pointer;
  border-radius:var(--r-xs); border:1px solid var(--hairline-strong); background:var(--input-bg);
  transition:background-color var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease);
}
.check .box input[type="radio"]{border-radius:50%}
.check .box svg{position:absolute; inset:3px; width:14px; height:14px; color:var(--accent-ink); opacity:0; pointer-events:none; transition:opacity var(--dur-1) var(--ease)}
.check .box input:checked{background:var(--accent); border-color:var(--accent)}
.check .box input[type="radio"]:checked{border-width:6px; background:var(--accent-ink)}
.check .box input:checked + svg{opacity:1}
.check .box input:focus-visible{outline:none; border-color:var(--accent); box-shadow:var(--focus-ring)}
.check .box input[aria-invalid="true"]{border-color:var(--danger)}
.check-text small{display:block; color:var(--muted); font-size:var(--t-small); line-height:1.45; margin-top:2px}

/* a product choice: a radio inside a bordered row */
.choice{display:flex; gap:12px; align-items:flex-start; padding:14px 16px; border:1px solid var(--hairline-strong); border-radius:var(--r-sm); background:var(--input-bg); cursor:pointer; transition:border-color var(--dur-2) var(--ease)}
.choice.is-checked{border-color:var(--accent); box-shadow:0 0 0 1px var(--accent)}
.choice .choice-price{margin-left:auto; font-weight:500; font-variant-numeric:tabular-nums; white-space:nowrap}

/* ------------------------------------------------------------------
   7. Status pill, money line, table
   ------------------------------------------------------------------ */
.pill{
  display:inline-flex; align-items:center; gap:6px; height:24px; padding:0 10px 0 8px;
  border-radius:var(--r-pill); font:500 12px/1 var(--font-text); letter-spacing:.01em; white-space:nowrap;
  background:var(--muted-tint); color:var(--muted);
}
.pill svg{width:13px; height:13px; flex:none}
.pill-waiting{background:var(--muted-tint); color:var(--muted)}
.pill-offered{background:var(--warning-tint); color:var(--warning-ink)}
.pill-held{background:var(--accent-tint); color:var(--accent)}
.pill-booked{background:var(--success-tint); color:var(--success-ink)}
.pill-cancelled{background:var(--danger-tint); color:var(--danger-ink)}

/* the money line is written only by the payments side */
.money{font:500 13px/1.4 var(--font-text); color:var(--success-ink); font-variant-numeric:tabular-nums; white-space:nowrap}
.money.is-pending{color:var(--muted)}

/* position:relative keeps absolutely positioned descendants (the .sr-only header text) inside the scroll container;
   without it the hidden span escapes to the page edge and a phone browser zooms the whole layout out to fit it */
.table-wrap{overflow-x:auto; -webkit-overflow-scrolling:touch; position:relative}
/* A table that can still be scrolled says so. The fade sits on the shell, which does not scroll, and is
   switched by the .has-more-x class the page sets from scrollLeft, so a table that fits and a table
   scrolled to its end both carry no fade; only opacity would move if it were animated, and nothing is
   painted over the sticky first column on the left. */
.shell-compact.has-more-x{position:relative}
.shell-compact.has-more-x::before{
  content:""; position:absolute; z-index:2; top:6px; right:6px; bottom:6px; width:36px;
  border-radius:0 var(--r-sm) var(--r-sm) 0; pointer-events:none;
  background:linear-gradient(to left, var(--raised) 22%, rgba(0,0,0,0));
}
.table{width:100%; border-collapse:collapse; font-size:15px; min-width:640px}
.table th{text-align:left; font:500 var(--t-small)/1.4 var(--font-text); letter-spacing:.01em; color:var(--muted); padding:12px 16px; border-bottom:1px solid var(--hairline)}
.table td{padding:0 16px; height:52px; border-bottom:1px solid var(--hairline); white-space:nowrap; vertical-align:middle}
.table tr:last-child td{border-bottom:0}
.table tbody tr:hover td{background:var(--surface)}
.table .num{text-align:right; font-variant-numeric:tabular-nums}
.table .sub{display:block; color:var(--muted); font-size:13px; line-height:1.3}
.table .who{font-weight:500}
.table .act{text-align:right}
.table .act a,.table .act button{font:500 14px/1 var(--font-text); color:var(--accent); text-decoration:none; background:none; border:0; padding:0; margin-left:16px}
.table .act a:hover,.table .act button:hover{text-decoration:underline}

/* ------------------------------------------------------------------
   8. Toast, empty state, skeleton
   ------------------------------------------------------------------ */
.toast{
  position:fixed; left:50%; bottom:24px; z-index:60; transform:translate(-50%, 0);
  display:flex; align-items:center; gap:12px; max-width:min(calc(100vw - 32px), 480px);
  padding:12px 12px 12px 16px; border-radius:var(--r-md);
  background:var(--raised); border:1px solid var(--hairline); box-shadow:var(--shadow-md); color:var(--ink); font-size:15px;
  transition:transform var(--dur-3) var(--ease), opacity var(--dur-3) var(--ease);
}
.toast > svg{width:20px; height:20px; flex:none; color:var(--accent)}
.toast-success > svg{color:var(--success)}
.toast-danger > svg{color:var(--danger)}
.toast.is-entering,.toast.is-leaving{opacity:0; transform:translate(-50%, 12px)}
.toast .close{margin-left:auto; width:32px; height:32px; border-radius:50%; border:0; background:transparent; color:var(--muted); display:grid; place-items:center; padding:0}
.toast .close svg{width:16px; height:16px}
.toast .close:hover{background:var(--muted-tint); color:var(--ink)}
.toast .close:focus-visible{outline:none; box-shadow:var(--focus-ring)}

.empty{display:grid; justify-items:center; text-align:center; gap:8px; padding:40px 24px}
.empty > svg{width:32px; height:32px; color:var(--muted); margin-bottom:8px}
.empty h3{font:600 var(--t-title)/1.3 var(--font-text); letter-spacing:-.01em}
.empty p{color:var(--muted); max-width:38ch}
.empty .btn{margin-top:12px}

.skeleton{display:block; background:var(--muted-tint); border-radius:var(--r-xs); min-height:1em; animation:sk-pulse 1.6s var(--ease-inout) infinite}
.skeleton-text{height:.9em; margin:.35em 0}
.skeleton-text.w-60{width:60%}
.skeleton-text.w-40{width:40%}
.skeleton-row{height:52px; border-radius:var(--r-sm)}
.skeleton-card{height:200px; border-radius:var(--r-md)}
@keyframes sk-pulse{0%,100%{opacity:1} 50%{opacity:.5}}

/* ------------------------------------------------------------------
   9. Nav pill and lockup
   ------------------------------------------------------------------ */
.nav{
  position:fixed; top:16px; left:50%; transform:translateX(-50%); z-index:50;
  height:var(--nav-h); padding:6px 6px 6px 18px; border-radius:var(--r-pill);
  background:var(--nav-bg); -webkit-backdrop-filter:blur(16px); backdrop-filter:blur(16px);
  border:1px solid var(--hairline); box-shadow:var(--shadow-md);
  display:flex; align-items:center; gap:20px; white-space:nowrap; max-width:calc(100vw - 32px);
}
.nav-links{display:none; gap:20px; margin:0 8px; padding:0; list-style:none}
@media (min-width:720px){ .nav-links{display:flex} }
.nav-links a{color:var(--muted); text-decoration:none; font:500 14px/1 var(--font-text); padding:8px 2px; transition:color var(--dur-2) var(--ease)}
.nav-links a:hover,.nav-links a[aria-current="page"]{color:var(--ink)}
.lockup{display:inline-flex; align-items:center; gap:.4em; color:var(--ink); text-decoration:none}
.lockup svg{width:1.1em; height:1.1em; flex:none; color:var(--ink)}
.lockup .pt{fill:var(--accent)}
.lockup .word{font:600 1em/1 var(--font-display); letter-spacing:-.03em}
.nav .lockup{font-size:18px}
.mark{color:var(--accent)}
.toggle{width:36px; height:36px; border-radius:50%; border:1px solid var(--hairline); background:var(--raised); color:var(--ink); display:grid; place-items:center; padding:0; transition:transform var(--dur-1) var(--ease)}
.toggle:active{transform:scale(.94)}
.toggle svg{width:18px; height:18px}
.toggle .ic-sun{display:none}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .toggle .ic-sun{display:block}
  :root:not([data-theme="light"]) .toggle .ic-moon{display:none}
}
:root[data-theme="dark"] .toggle .ic-sun{display:block}
:root[data-theme="dark"] .toggle .ic-moon{display:none}
:root[data-theme="light"] .toggle .ic-sun{display:none}
:root[data-theme="light"] .toggle .ic-moon{display:block}
.toggle:focus-visible{outline:none; border-color:var(--accent); box-shadow:var(--focus-ring)}

/* ------------------------------------------------------------------
   10. Photographs: one treatment, grain scoped to the photo, never page-wide
   ------------------------------------------------------------------ */
.photo{position:relative; overflow:hidden; background:var(--muted-tint)}
.photo img{width:100%; height:100%; object-fit:cover; filter:var(--photo-filter)}
.photo::after{
  content:""; position:absolute; inset:0; pointer-events:none; opacity:var(--grain-opacity); mix-blend-mode:soft-light;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0 0.5 0 0 0 0.35 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size:160px 160px;
}
.photo-16-10{aspect-ratio:16/10}
.photo-4-3{aspect-ratio:4/3}
.photo-4-5{aspect-ratio:4/5}
.photo-1-1{aspect-ratio:1/1}
.photo-r-md{border-radius:var(--r-md)}
.photo-r-lg{border-radius:var(--r-lg)}

/* ------------------------------------------------------------------
   11. Dialog, rail, filters, segmented control, tile, frame fallback
   ------------------------------------------------------------------ */
/* confirm dialog: a card-size shell over a scrim; the right-hand action is
   primary for a send and .btn-danger for something that cannot be undone */
.scrim{position:fixed; inset:0; z-index:70; background:var(--scrim); opacity:0; transition:opacity var(--dur-2) var(--ease)}
.scrim.is-open{opacity:1}
.dialog{
  position:fixed; z-index:71; left:50%; top:50%; transform:translate(-50%,-50%);
  width:min(calc(100vw - 32px), 440px); margin:0; padding:8px;
  background:var(--surface); border:1px solid var(--hairline); border-radius:var(--r-lg);
  box-shadow:var(--shadow-lg); color:var(--ink);
}
.dialog > .core{display:grid; gap:12px}
.dialog h2{font:600 var(--t-title)/1.3 var(--font-text); letter-spacing:-.01em}
.dialog p{color:var(--muted)}
.dialog .actions{display:flex; flex-wrap:wrap; justify-content:flex-end; gap:12px; margin-top:8px}

/* dashboard rail: one pill per section, a tabular count on the right */
.rail{display:flex; flex-direction:column; gap:4px; margin:0; padding:0; list-style:none}
.rail a{display:flex; align-items:center; gap:8px; padding:10px 14px; border-radius:var(--r-pill); color:var(--muted); text-decoration:none; font:500 15px/1 var(--font-text); transition:background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease)}
.rail a:hover{background:var(--muted-tint); color:var(--ink)}
.rail a[aria-current="page"]{background:var(--accent-tint); color:var(--accent)}
.rail .count{margin-left:auto; font-size:13px; font-variant-numeric:tabular-nums}
@media (max-width:899px){
  .rail{flex-direction:row; gap:8px; overflow-x:auto; -webkit-overflow-scrolling:touch}
  .rail a{white-space:nowrap}
}

/* filter pills: real toggle buttons, state in aria-pressed */
.filters{display:flex; flex-wrap:wrap; gap:8px}
.filter{height:32px; padding:0 14px; border-radius:var(--r-pill); border:1px solid var(--hairline); background:var(--raised); color:var(--muted); font:500 14px/1 var(--font-text)}
.filter:hover{color:var(--ink)}
.filter[aria-pressed="true"]{background:var(--accent-tint); border-color:transparent; color:var(--accent)}
.filter:focus-visible{outline:none; border-color:var(--accent); box-shadow:var(--focus-ring)}

/* segmented control: radios in a pill group (Came / Missed / Clear) */
.seg{display:inline-flex; gap:2px; padding:2px; border:1px solid var(--hairline-strong); border-radius:var(--r-pill); background:var(--input-bg)}
.seg label{position:relative; display:inline-flex; margin:0}
.seg input{position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer}
.seg .txt{display:inline-flex; align-items:center; height:32px; padding:0 12px; border-radius:var(--r-pill); color:var(--muted); font:500 14px/1 var(--font-text); white-space:nowrap; transition:background-color var(--dur-2) var(--ease), color var(--dur-2) var(--ease)}
.seg input:checked + .txt{background:var(--accent); color:var(--accent-ink)}
.seg input:focus-visible + .txt{box-shadow:var(--focus-ring)}

/* the Places strip: one compact tile per class */
.tiles{display:grid; grid-template-columns:repeat(auto-fill, minmax(240px, 1fr)); gap:16px}
.tile > .core{display:grid; gap:6px}
.tile h3{font:600 var(--t-title)/1.3 var(--font-text); letter-spacing:-.01em}
.tile .meta,.tile .num{color:var(--muted); font-size:14px}
.tile .num{font-variant-numeric:tabular-nums}

/* the device frame's failure state, inside the screen */
.screen-fallback{position:absolute; inset:0; display:grid; place-content:center; justify-items:center; gap:12px; padding:24px; text-align:center; background:var(--raised); color:var(--ink)}
.screen-fallback[hidden]{display:none}
.screen-fallback svg{width:32px; height:32px; color:var(--accent)}
.screen-fallback a{color:var(--accent)}

/* ------------------------------------------------------------------
   12. Motion helpers and accessibility
   ------------------------------------------------------------------ */
/* the landing adds html.has-gsap only after GSAP has loaded, so nothing can stay hidden */
html.has-gsap [data-reveal]{visibility:hidden}
:focus-visible{outline:2px solid var(--accent); outline-offset:3px}
.btn:focus-visible,.input:focus-visible,.toggle:focus-visible{outline:none}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{transition-duration:0s !important; animation:none !important; scroll-behavior:auto !important}
  .btn:hover .ic,.btn:active,.toggle:active,.shell-lift:hover{transform:none}
  .places.is-pending .dot{transform:none}
  .places.is-pending .txt{opacity:1}
  .toast.is-entering{opacity:1; transform:translate(-50%, 0)}
  .scrim{opacity:1}
  html.has-gsap [data-reveal]{visibility:visible}
}
