@import url("../tokens/fonts.css");

/* ==========================================================================
   Groove — the 1970s, warm and groovy.
   Fat round type, crisp stacked stripes, arches, pills and lava-lamp blobs.
   Colours, spacing, radii, shadows, durations and easings come from tokens.css.
   Motion rules: transform/opacity only (blobs morph border-radius on hover only);
   entrance animations fill BACKWARDS; shadows change only on one element's state.
   ========================================================================== */

:root {
  /* easing + duration aliases with fallbacks, so the bundle works before tokens load */
  --gv-boing: var(--ease-boing, cubic-bezier(.34, 1.8, .5, 1));
  --gv-groove: var(--ease-groove, cubic-bezier(.22, 1, .36, 1));
  --gv-wobble: var(--ease-wobble, cubic-bezier(.3, 1.45, .55, 1));
  --gv-squish: var(--ease-squish, cubic-bezier(.4, 0, .6, 1));
  --gv-exit: var(--ease-exit, cubic-bezier(.55, 0, .8, .2));
  --gv-t-press: var(--dur-press, 110ms);
  --gv-t-hover: var(--dur-hover, 200ms);
  --gv-t-pop: var(--dur-pop, 420ms);
  --gv-t-wobble: var(--dur-wobble, 640ms);
  --gv-t-swoosh: var(--dur-swoosh, 900ms);
  --gv-t-morph: var(--dur-morph, 1600ms);
  --gv-t-spin: var(--dur-spin, 1800ms);
  /* surface-aware text colours (room by default) */
  --gv-fg: var(--ink);
  --gv-fg-soft: var(--ink-soft);
  --gv-accent: var(--accent-text);
  --gv-tip-bg: var(--chocolate);
  --gv-tip-fg: var(--cream);
  --gv-track: var(--room-sunk);
  --gv-notch: var(--room);
  --gv-avocado-lip: #6e7a26;
  color-scheme: light;
}
[data-theme="dark"] {
  color-scheme: dark;
  --gv-tip-bg: var(--cream);
  --gv-tip-fg: var(--chocolate);
}

body {
  margin: 0;
  background: var(--room);
  color: var(--ink);
  font: 500 16px/26px var(--font-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
*, *::before, *::after { box-sizing: border-box; }

/* ---------- type helpers ---------- */
.gv-d { font: 400 76px/72px var(--font-display); letter-spacing: -.01em; margin: 0; }
.gv-title { font: 400 44px/46px var(--font-display); margin: 0; }
.gv-h { font: 400 26px/30px var(--font-display); margin: 0; }
.gv-lead { font: 600 20px/30px var(--font-body); margin: 0; }
.gv-p { font: 500 16px/26px var(--font-body); margin: 0; }
.gv-small { font: 600 14px/20px var(--font-body); margin: 0; }
.gv-overline { font: 800 12px/16px var(--font-body); letter-spacing: .14em; text-transform: uppercase; }
.gv-soft { color: var(--gv-fg-soft); }
.gv-accent { color: var(--gv-accent); }
.gv-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* ---------- preview stage + layout helpers ---------- */
.gv-stage { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); padding: var(--space-8); }
.gv-stage--top { align-items: flex-start; }
.gv-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); }
.gv-col { display: flex; flex-direction: column; gap: var(--space-4); }
.gv-cap { width: 100%; color: var(--ink-soft); font: 800 12px/16px var(--font-body); letter-spacing: .14em; text-transform: uppercase; }
@media (max-width: 520px) { .gv-stage { padding: var(--space-4); } }

/* ---------- tones: set fill + text colours for everything inside ---------- */
.gv-tone-face { --gv-fill: var(--face); --gv-fg: var(--ink); --gv-fg-soft: var(--ink-soft); --gv-accent: var(--accent-text); --gv-track: var(--room-sunk); }
.gv-tone-sunk { --gv-fill: var(--room-sunk); --gv-fg: var(--ink); --gv-fg-soft: var(--ink-soft); --gv-accent: var(--accent-text); }
.gv-tone-orange { --gv-fill: var(--orange); --gv-fg: var(--chocolate); --gv-fg-soft: var(--chocolate); --gv-accent: var(--chocolate); --gv-lip: var(--rust); --gv-track: #fff3dc59; }
.gv-tone-mustard { --gv-fill: var(--mustard); --gv-fg: var(--chocolate); --gv-fg-soft: var(--chocolate); --gv-accent: var(--chocolate); --gv-lip: var(--orange); --gv-track: #fff3dc66; }
.gv-tone-avocado { --gv-fill: var(--avocado); --gv-fg: var(--chocolate); --gv-fg-soft: var(--chocolate); --gv-accent: var(--chocolate); --gv-lip: var(--gv-avocado-lip); --gv-track: #fff3dc59; }
.gv-tone-rust { --gv-fill: var(--rust); --gv-fg: var(--cream); --gv-fg-soft: var(--cream); --gv-accent: var(--mustard); --gv-lip: var(--chocolate); --gv-track: #341d1066; }
.gv-tone-chocolate { --gv-fill: var(--chocolate); --gv-fg: var(--cream); --gv-fg-soft: #e9d2ad; --gv-accent: var(--mustard); --gv-lip: #1a0e07; --gv-track: #fff3dc24; --gv-notch: var(--room); }
.gv-tone-cream { --gv-fill: var(--cream); --gv-fg: var(--chocolate); --gv-fg-soft: #6b4733; --gv-accent: var(--rust); --gv-lip: var(--mustard); --gv-track: #ecd9b6; }
[class*="gv-tone-"] { color: var(--gv-fg); }

/* ---------- focus: chocolate ring on cream, mustard ring on the disco floor ---------- */
.gv-btn:focus-visible, .gv-ibtn:focus-visible, .gv-tag:focus-visible, .gv-tabs__tab:focus-visible, .gv-seg__opt:focus-visible,
.gv-select__btn:focus-visible, .gv-card--click:focus-visible, .gv-blob:focus-visible, .gv-toast button:focus-visible,
.gv-tabs__panel:focus-visible, .gv-tipwrap [tabindex]:focus-visible {
  outline: 3px solid var(--focus); outline-offset: 3px;
}

/* ---------- the mark: the record spins while you hover it ---------- */
.gv-mark { display: inline-block; flex: none; width: calc(var(--size, 48px) * 72 / 56); height: var(--size, 48px); line-height: 0; }
.gv-mark svg { display: block; width: 100%; height: 100%; overflow: visible; }
.gv-mark__rec { transform-box: fill-box; transform-origin: 50% 50%; }
.gv-mark:hover .gv-mark__rec, a:hover > .gv-mark .gv-mark__rec { animation: gv-spin var(--gv-t-spin) linear infinite; }

/* ---------- hover-lift targets own a stacking context so their invisible ::after skirt is hit-testable ---------- */
.gv-btn, .gv-ibtn, .gv-card--click, .gv-ticket { z-index: 0; }

/* ---------- icons ---------- */
.gv-icon { display: inline-flex; flex: none; line-height: 0; }
.gv-icon svg { display: block; }

/* ==========================================================================
   Keyframes
   ========================================================================== */
@keyframes gv-boing {
  0% { transform: scale(1.06, .88); }
  35% { transform: scale(.95, 1.07); }
  62% { transform: scale(1.03, .97); }
  82% { transform: scale(.995, 1.01); }
  100% { transform: none; }
}
@keyframes gv-pop {
  0% { transform: scale(.7); }
  55% { transform: scale(1.14); }
  80% { transform: scale(.96); }
  100% { transform: none; }
}
@keyframes gv-squish {
  0% { transform: none; }
  35% { transform: scale(1.32, .78); }
  70% { transform: scale(.92, 1.08); }
  100% { transform: none; }
}
@keyframes gv-wobble-in {
  0% { opacity: 0; transform: translateY(28px) rotate(-3.5deg) scale(.96); }
  50% { opacity: 1; transform: translateY(-5px) rotate(1.6deg) scale(1.005); }
  74% { transform: translateY(1.5px) rotate(-.7deg); }
  90% { transform: translateY(0) rotate(.25deg); }
  100% { transform: none; }
}
@keyframes gv-rise { from { opacity: 0; transform: translateY(10px); } }
@keyframes gv-fade { from { opacity: 0; } }
@keyframes gv-swoosh { from { transform: translateX(-104%); } }
@keyframes gv-swoosh-y { from { transform: translateY(-104%); } }
@keyframes gv-arch-up { 0% { opacity: 0; transform: scale(.25); } 40% { opacity: 1; } 100% { transform: none; } }
@keyframes gv-spin { to { transform: rotate(360deg); } }
@keyframes gv-shake { 0%, 100% { transform: none; } 20% { transform: translateX(-7px) rotate(-1deg); } 45% { transform: translateX(6px) rotate(.8deg); } 70% { transform: translateX(-3px); } }
@keyframes gv-menu-in { from { opacity: 0; transform: translateY(-10px) scale(.94) rotate(-1.8deg); } }
@keyframes gv-modal-in {
  0% { opacity: 0; transform: translateY(70px) rotate(3deg) scale(.92); }
  55% { opacity: 1; transform: translateY(-8px) rotate(-1.2deg) scale(1.01); }
  80% { transform: translateY(2px) rotate(.4deg); }
  100% { transform: none; }
}
@keyframes gv-toast-in { 0% { opacity: 0; transform: translateY(48px) rotate(4deg) scale(.9); } 60% { opacity: 1; } 100% { transform: none; } }
@keyframes gv-indet { from { transform: translateX(-100%); } to { transform: translateX(260%); } }
/* blob morph: no 0% frame, so it starts from the blob's own resting shape */
@keyframes gv-morph {
  25% { border-radius: 40% 60% 62% 38% / 54% 38% 62% 46%; }
  50% { border-radius: 63% 37% 45% 55% / 38% 62% 38% 62%; }
  75% { border-radius: 46% 54% 36% 64% / 62% 46% 54% 38%; }
  100% { border-radius: 55% 45% 58% 42% / 44% 56% 44% 56%; }
}

/* ---------- the wobble-in entrance (cards, widgets): backwards fill only ---------- */
.gv-wobble { animation: gv-wobble-in var(--gv-t-wobble) cubic-bezier(.25, .8, .4, 1) backwards; animation-delay: calc(var(--i, 0) * 70ms); transform-origin: 40% 100%; }

/* ---------- organic blob shapes (avatars, blobs, toast icons) ---------- */
.gv-shape-0 { border-radius: 58% 42% 54% 46% / 52% 58% 42% 48%; }
.gv-shape-1 { border-radius: 44% 56% 48% 52% / 60% 44% 56% 40%; }
.gv-shape-2 { border-radius: 52% 48% 40% 60% / 46% 54% 46% 54%; }
.gv-shape-3 { border-radius: 62% 38% 56% 44% / 48% 52% 48% 52%; }

/* ==========================================================================
   Button: a fat pill on a coloured lip. Hover lifts, press squishes, release boings.
   `translate` carries hover/press; `transform` carries the squish and the boing,
   so the two never fight.
   ========================================================================== */
.gv-btn {
  --gv-bg: var(--orange); --gv-txt: var(--chocolate); --gv-lip: var(--rust); --gv-bd: transparent;
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  height: 48px; padding: 0 var(--space-6); margin-bottom: 4px;
  border: 2.5px solid var(--gv-bd); border-radius: var(--radius-pill);
  background: var(--gv-bg); color: var(--gv-txt);
  font: 400 17px/1 var(--font-display); letter-spacing: .01em; white-space: nowrap; text-decoration: none;
  box-shadow: 0 4px 0 var(--gv-lip);
  cursor: pointer; user-select: none; -webkit-tap-highlight-color: transparent;
  transition: translate var(--gv-t-hover) var(--gv-groove), box-shadow var(--gv-t-hover) var(--gv-groove), transform var(--gv-t-press) var(--gv-squish), background-color var(--gv-t-hover);
}
.gv-btn::after { content: ""; position: absolute; inset: -3px -3px -10px -3px; border-radius: inherit; z-index: -1; }
.gv-btn__label { padding-top: 1px; }
.gv-btn:hover { translate: 0 -2px; box-shadow: 0 6px 0 var(--gv-lip); }
.gv-btn:active { translate: 0 3px; transform: scale(1.06, .88); box-shadow: 0 1px 0 var(--gv-lip); transition-duration: var(--gv-t-press); }
.gv-btn.is-boing { animation: gv-boing 460ms linear; }
.gv-btn--primary { --gv-bg: var(--orange); --gv-txt: var(--chocolate); --gv-lip: var(--rust); }
.gv-btn--sunny { --gv-bg: var(--mustard); --gv-txt: var(--chocolate); --gv-lip: var(--orange); }
.gv-btn--avocado { --gv-bg: var(--avocado); --gv-txt: var(--chocolate); --gv-lip: var(--gv-avocado-lip); }
.gv-btn--danger { --gv-bg: var(--rust); --gv-txt: var(--cream); --gv-lip: var(--chocolate); }
[data-theme="dark"] .gv-btn--danger { --gv-lip: #120a05; }
.gv-btn--outline { --gv-bg: var(--face); --gv-txt: var(--ink); --gv-lip: var(--ink); --gv-bd: var(--ink); }
.gv-btn--ghost { --gv-bg: transparent; --gv-txt: var(--gv-fg); --gv-lip: transparent; box-shadow: none; }
.gv-btn--ghost:hover { background: color-mix(in srgb, currentColor 10%, transparent); box-shadow: none; }
.gv-btn--ghost:active { box-shadow: none; }
.gv-btn--sm { height: 38px; padding: 0 var(--space-4); font-size: 15px; gap: 6px; }
.gv-btn--lg { height: 60px; padding: 0 32px; font-size: 21px; gap: 10px; }
.gv-btn--block { display: flex; width: 100%; }
.gv-btn:disabled, .gv-btn[aria-disabled="true"] { --gv-bg: var(--room-sunk); --gv-txt: var(--ink-soft); --gv-lip: transparent; --gv-bd: transparent; cursor: not-allowed; translate: none; transform: none; box-shadow: none; }
.gv-btn.is-loading { --gv-bg: var(--mustard); --gv-txt: var(--chocolate); --gv-lip: var(--orange); --gv-bd: transparent; cursor: progress; }
.gv-btn__spin { margin-left: -4px; }

/* ==========================================================================
   IconButton
   ========================================================================== */
.gv-ibtn {
  --gv-bg: var(--room-sunk); --gv-txt: var(--gv-fg); --gv-lip: transparent;
  position: relative; display: inline-grid; place-items: center; flex: none;
  width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%;
  background: var(--gv-bg); color: var(--gv-txt); box-shadow: 0 3px 0 var(--gv-lip);
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: translate var(--gv-t-hover) var(--gv-groove), transform var(--gv-t-press) var(--gv-squish), background-color var(--gv-t-hover), box-shadow var(--gv-t-hover);
}
.gv-ibtn::after { content: ""; position: absolute; inset: -3px -3px -8px -3px; border-radius: inherit; z-index: -1; }
.gv-ibtn:hover { translate: 0 -2px; }
.gv-ibtn:active { translate: 0 2px; transform: scale(1.1, .86); }
.gv-ibtn.is-boing { animation: gv-boing 460ms linear; }
.gv-ibtn--solid { --gv-bg: var(--orange); --gv-txt: var(--chocolate); --gv-lip: var(--rust); }
.gv-ibtn--soft { --gv-bg: var(--room-sunk); }
.gv-tone-face .gv-ibtn--soft { --gv-bg: var(--room-sunk); }
.gv-ibtn--ghost { --gv-bg: transparent; }
.gv-ibtn--ghost:hover, .gv-ibtn--soft:hover { background: color-mix(in srgb, currentColor 13%, var(--gv-bg)); }
.gv-ibtn--sm { width: 36px; height: 36px; }
.gv-ibtn--lg { width: 58px; height: 58px; }
.gv-ibtn[aria-pressed="true"] { --gv-bg: var(--mustard); --gv-txt: var(--chocolate); --gv-lip: var(--orange); }
.gv-ibtn[aria-pressed="true"]:hover { background: var(--mustard); }
.gv-ibtn[aria-pressed="true"] .gv-icon svg path { fill: currentColor; }
.gv-ibtn .gv-icon.is-pop { animation: gv-pop 480ms linear; }
.gv-ibtn:disabled { opacity: .45; cursor: not-allowed; translate: none; transform: none; }
.gv-ibtn__count {
  position: absolute; top: -4px; right: -6px; min-width: 22px; height: 22px; padding: 0 6px; border-radius: 999px;
  background: var(--rust); color: var(--cream); font: 800 12px/22px var(--font-body); text-align: center;
  box-shadow: 0 0 0 3px var(--room);
}

/* ==========================================================================
   Toggle: stacked stripes slide in behind a squishy knob
   ========================================================================== */
.gv-toggle { position: relative; display: inline-flex; align-items: center; gap: var(--space-3); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.gv-toggle__input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.gv-toggle__track {
  position: relative; flex: none; width: 62px; height: 36px; border-radius: var(--radius-pill);
  background: var(--gv-track); border: 2.5px solid var(--ink-soft); overflow: hidden;
  transition: border-color var(--gv-t-hover);
}
.gv-toggle__stripes { position: absolute; inset: 0; display: flex; flex-direction: column; transform: translateX(-102%); transition: transform 480ms var(--gv-groove); }
.gv-toggle__stripes i { flex: 1; }
.gv-toggle__stripes i:nth-child(1) { background: var(--mustard); }
.gv-toggle__stripes i:nth-child(2) { background: var(--orange); }
.gv-toggle__stripes i:nth-child(3) { background: var(--rust); }
.gv-toggle__knob {
  position: absolute; top: 3px; left: 3px; width: 25px; height: 25px; border-radius: 50%;
  background: var(--ink-soft); translate: 0 0;
  transition: translate 460ms var(--gv-boing), background-color var(--gv-t-hover), box-shadow var(--gv-t-hover);
}
.gv-toggle__knob.is-squish { animation: gv-squish 420ms ease-out; }
.gv-toggle__input:checked + .gv-toggle__track { border-color: var(--accent-text); }
.gv-toggle__input:checked + .gv-toggle__track .gv-toggle__stripes { transform: none; }
.gv-toggle__input:checked + .gv-toggle__track .gv-toggle__knob { translate: 26px 0; background: var(--cream); box-shadow: 0 0 0 2.5px var(--chocolate); }
.gv-toggle:hover .gv-toggle__knob { scale: 1.08; }
.gv-toggle__input:focus-visible + .gv-toggle__track { outline: 3px solid var(--focus); outline-offset: 3px; }
.gv-toggle__text { display: flex; flex-direction: column; }
.gv-toggle__label { font: 700 16px/22px var(--font-body); color: var(--gv-fg); }
.gv-toggle__hint { font: 600 14px/20px var(--font-body); color: var(--gv-fg-soft); }
.gv-toggle.is-disabled { opacity: .5; cursor: not-allowed; }

/* ==========================================================================
   Checkbox + Radio (the radio is a tiny record)
   ========================================================================== */
.gv-check, .gv-radio { position: relative; display: inline-flex; align-items: flex-start; gap: var(--space-3); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.gv-check__input, .gv-radio__input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.gv-check__box {
  flex: none; width: 26px; height: 26px; display: grid; place-items: center;
  border-radius: 9px; border: 2.5px solid var(--ink-soft); background: var(--face); color: var(--chocolate);
  transition: background-color var(--gv-t-hover), border-color var(--gv-t-hover), translate var(--gv-t-hover) var(--gv-groove);
}
.gv-check__box svg { transform: scale(0) rotate(-25deg); transition: transform var(--gv-t-pop) var(--gv-boing); }
.gv-check__input:checked + .gv-check__box { background: var(--orange); border-color: var(--accent-text); }
.gv-check__input:checked + .gv-check__box svg { transform: none; }
.gv-check__input:indeterminate + .gv-check__box { background: var(--mustard); border-color: var(--accent-text); }
.gv-check__box svg, .gv-check__box::before { grid-area: 1 / 1; }
.gv-check__input:indeterminate + .gv-check__box svg { transform: scale(0); }
.gv-check__input:indeterminate + .gv-check__box::before { content: ""; width: 12px; height: 3.5px; border-radius: 2px; background: var(--chocolate); grid-area: 1 / 1; }
.gv-check__box.is-pop { animation: gv-pop 460ms linear; }
.gv-check:hover .gv-check__box, .gv-radio:hover .gv-radio__dot { translate: 0 -2px; }
.gv-check__input:focus-visible + .gv-check__box, .gv-radio__input:focus-visible + .gv-radio__dot { outline: 3px solid var(--focus); outline-offset: 3px; }
.gv-check__text { display: flex; flex-direction: column; padding-top: 1px; }
.gv-check__label { font: 700 16px/24px var(--font-body); color: var(--gv-fg); }
.gv-check__hint { font: 600 14px/20px var(--font-body); color: var(--gv-fg-soft); }
.gv-check.is-disabled, .gv-radio.is-disabled { opacity: .5; cursor: not-allowed; }
.gv-radio__dot {
  flex: none; width: 26px; height: 26px; display: grid; place-items: center; border-radius: 50%;
  border: 2.5px solid var(--ink-soft); background: var(--face);
  transition: border-color var(--gv-t-hover), translate var(--gv-t-hover) var(--gv-groove);
}
.gv-radio__dot svg { display: block; width: 22px; height: 22px; }
.gv-radio__disc { transform-box: view-box; transform-origin: 50% 50%; transform: scale(0) rotate(-120deg); transition: transform 560ms var(--gv-boing); }
.gv-radio__vinyl { fill: var(--chocolate); }
.gv-radio__l1 { fill: var(--orange); } .gv-radio__l2 { fill: var(--mustard); } .gv-radio__hole { fill: var(--cream); }
.gv-radio__input:checked + .gv-radio__dot { border-color: var(--accent-text); }
.gv-radio__input:checked + .gv-radio__dot .gv-radio__disc { transform: none; }
.gv-radiogroup { border: 0; margin: 0; padding: 0; min-width: 0; }
.gv-radiogroup legend { padding: 0; margin-bottom: var(--space-3); }
.gv-radiogroup__opts { display: flex; flex-direction: column; gap: var(--space-3); }
.gv-radiogroup--inline .gv-radiogroup__opts { flex-direction: row; flex-wrap: wrap; gap: var(--space-3) var(--space-6); }

/* ==========================================================================
   TextField: focus slides a stripe in along the bottom
   ========================================================================== */
.gv-field { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.gv-field__label { font: 800 12px/16px var(--font-body); letter-spacing: .14em; text-transform: uppercase; color: var(--gv-fg); }
.gv-field__box {
  position: relative; display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 18px;
  border-radius: var(--radius-md); background: var(--face); border: 2px solid var(--ink-soft); overflow: hidden;
  color: var(--ink); transition: border-color var(--gv-t-hover);
}
.gv-field__box > .gv-icon { color: var(--ink-soft); }
.gv-field__input {
  flex: 1; min-width: 0; border: 0; background: transparent; outline: none; padding: 13px 0;
  font: 600 16px/24px var(--font-body); color: var(--ink);
}
.gv-field__input::placeholder { color: var(--ink-soft); opacity: 1; font-weight: 500; }
.gv-field__stripe { position: absolute; left: 0; right: 0; bottom: 0; height: 9px; display: flex; flex-direction: column; transform: translateX(-102%); transition: transform 560ms var(--gv-groove); pointer-events: none; }
.gv-field__stripe i { flex: 1; }
.gv-field__stripe i:nth-child(1) { background: var(--mustard); }
.gv-field__stripe i:nth-child(2) { background: var(--orange); }
.gv-field__stripe i:nth-child(3) { background: var(--rust); }
.gv-field__box:hover { border-color: var(--ink); }
.gv-field__box:focus-within { border-color: var(--ink); }
.gv-field__box:focus-within .gv-field__stripe { transform: none; }
.gv-field__box:focus-within > .gv-icon { color: var(--ink); }
.gv-field__help { display: flex; align-items: center; gap: 6px; min-height: 0; font: 600 14px/20px var(--font-body); color: var(--gv-fg-soft); }
.gv-field__help:empty { display: none; }
.gv-field.is-error .gv-field__box { border-color: var(--error); }
.gv-field.is-error .gv-field__help { color: var(--error); }
.gv-field.is-error .gv-field__stripe i { background: var(--rust); }
.gv-field__box.is-shake { animation: gv-shake 420ms ease-out; }
.gv-field--multi .gv-field__box { align-items: flex-start; padding-top: 2px; }
.gv-field--multi .gv-field__input { resize: vertical; min-height: 96px; }
.gv-field--lg .gv-field__box { min-height: 60px; }
.gv-field--lg .gv-field__input { font-size: 18px; }
.gv-field__input:disabled { cursor: not-allowed; color: var(--ink-soft); }

/* ==========================================================================
   Select: a pill-ish button and a menu that wobbles open
   ========================================================================== */
.gv-select { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.gv-select__wrap { position: relative; }
.gv-select__btn {
  width: 100%; display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 0 12px 0 18px;
  border-radius: var(--radius-md); border: 2px solid var(--ink-soft); background: var(--face); color: var(--ink);
  font: 700 16px/24px var(--font-body); text-align: left; cursor: pointer;
  transition: border-color var(--gv-t-hover), translate var(--gv-t-hover) var(--gv-groove);
}
.gv-select__btn > .gv-icon:first-child { color: var(--ink-soft); }
.gv-select__btn:hover { border-color: var(--ink); }
.gv-select__btn.is-boing { animation: gv-boing 440ms linear; }
.gv-select__value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gv-select__value.is-placeholder { color: var(--ink-soft); font-weight: 600; }
.gv-select__chev { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: var(--room-sunk); color: var(--ink); transition: transform var(--gv-t-pop) var(--gv-boing); }
.gv-select.is-open .gv-select__chev { transform: rotate(180deg); }
.gv-select.is-open .gv-select__btn { border-color: var(--ink); }
.gv-select__menu {
  position: absolute; z-index: 40; left: 0; right: 0; top: calc(100% + 8px); margin: 0; padding: 6px; list-style: none;
  max-height: 284px; overflow: auto; background: var(--face); color: var(--ink);
  border: 2px solid var(--line); border-radius: var(--radius-md); box-shadow: var(--shadow-float);
  transform-origin: 50% 0; outline: none;
}
.gv-select__menu.is-in { animation: gv-menu-in 420ms var(--gv-wobble); }
.gv-select__opt { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 12px; cursor: pointer; font: 700 15px/20px var(--font-body); }
.gv-select__opt.is-active { background: var(--room-sunk); }
.gv-select__menu:focus-visible .gv-select__opt.is-active { box-shadow: inset 0 0 0 2px var(--focus); }
.gv-select__opt[aria-selected="true"] { color: var(--accent-text); }
.gv-select__optlabel { display: flex; flex-direction: column; min-width: 0; }
.gv-select__optlabel small { font: 600 13px/18px var(--font-body); color: var(--ink-soft); }
.gv-select__swatch { flex: none; width: 20px; height: 20px; border-radius: 7px; }
.gv-select__tick { margin-left: auto; opacity: 0; transform: scale(.4); transition: transform var(--gv-t-pop) var(--gv-boing), opacity .15s; }
.gv-select__opt[aria-selected="true"] .gv-select__tick { opacity: 1; transform: none; }

/* ==========================================================================
   Tabs: a three-band stripe slides under the chosen tab
   ========================================================================== */
.gv-tabs { min-width: 0; }
.gv-tabs__list { position: relative; display: flex; gap: 2px; border-bottom: 2px solid var(--line); overflow-x: auto; scrollbar-width: none; }
.gv-tabs__list::-webkit-scrollbar { display: none; }
.gv-tabs__tab {
  position: relative; display: inline-flex; align-items: center; gap: 8px; flex: none;
  padding: 10px 16px 18px; border: 0; background: none; border-radius: 14px 14px 0 0; cursor: pointer;
  font: 400 19px/22px var(--font-display); color: var(--gv-fg-soft); transition: color var(--gv-t-hover), translate var(--gv-t-hover) var(--gv-groove);
}
.gv-tabs__tab:hover { color: var(--gv-fg); translate: 0 -2px; }
.gv-tabs__tab[aria-selected="true"] { color: var(--gv-fg); }
.gv-tabs__tab:focus-visible { outline-offset: -3px; }
.gv-tabs__count { min-width: 22px; height: 22px; padding: 0 7px; border-radius: 999px; background: var(--room-sunk); color: var(--ink); font: 800 12px/22px var(--font-body); }
.gv-tabs__tab[aria-selected="true"] .gv-tabs__count { background: var(--mustard); color: var(--chocolate); }
.gv-tabs__bar { position: absolute; left: 0; bottom: 0; width: 100px; height: 9px; display: flex; flex-direction: column; transform-origin: 0 0; pointer-events: none; border-radius: 3px 3px 0 0; overflow: hidden; }
.gv-tabs.is-ready .gv-tabs__bar { transition: transform 520ms var(--gv-wobble); }
.gv-tabs__bar i { flex: 1; }
.gv-tabs__bar i:nth-child(1) { background: var(--mustard); }
.gv-tabs__bar i:nth-child(2) { background: var(--orange); }
.gv-tabs__bar i:nth-child(3) { background: var(--rust); }
.gv-tabs__panel { padding-top: var(--space-6); outline: none; }
.gv-tabs__panel.is-in { animation: gv-rise 420ms var(--gv-groove); }

/* ==========================================================================
   SegmentedControl: a mustard thumb that boings between options
   ========================================================================== */
.gv-seg {
  position: relative; isolation: isolate; display: inline-grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr));
  padding: 5px; border-radius: var(--radius-pill); background: var(--gv-track); max-width: 100%;
}
.gv-seg--block { display: grid; width: 100%; }
.gv-seg__thumb {
  position: absolute; z-index: -1; top: 5px; bottom: 5px; left: 5px; width: calc((100% - 10px) / var(--n));
  border-radius: var(--radius-pill); background: var(--mustard); box-shadow: 0 3px 0 var(--orange);
  translate: calc(var(--i, 0) * 100%) 0; transition: translate 480ms var(--gv-boing);
}
.gv-seg__thumb.is-squish { animation: gv-squish 440ms ease-out; }
.gv-seg__opt {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 0;
  height: 40px; padding: 0 18px; border: 0; background: none; border-radius: var(--radius-pill); cursor: pointer;
  font: 800 15px/1 var(--font-body); color: var(--gv-fg-soft); white-space: nowrap; transition: color var(--gv-t-hover);
}
.gv-seg__opt span { overflow: hidden; text-overflow: ellipsis; }
.gv-seg__opt:hover { color: var(--gv-fg); }
.gv-seg__opt[aria-checked="true"] { color: var(--chocolate); }
.gv-seg--sm .gv-seg__opt { height: 32px; padding: 0 12px; font-size: 13px; }
.gv-seg--sm { padding: 4px; }
.gv-seg--sm .gv-seg__thumb { top: 4px; bottom: 4px; left: 4px; width: calc((100% - 8px) / var(--n)); }
.gv-tone-chocolate .gv-seg__opt, .gv-tone-rust .gv-seg__opt { color: var(--gv-fg); }
.gv-tone-chocolate .gv-seg__opt[aria-checked="true"], .gv-tone-rust .gv-seg__opt[aria-checked="true"] { color: var(--chocolate); }

/* ==========================================================================
   Slider: a rainbow-stripe fill and a squishy cream knob with an arch bubble
   ========================================================================== */
.gv-slider { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.gv-slider__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.gv-slider__out { font: 400 20px/24px var(--font-display); color: var(--gv-fg); }
.gv-slider__rail { position: relative; height: 40px; --p: 0; }
.gv-slider__track { position: absolute; left: 0; right: 0; top: 50%; height: 14px; margin-top: -7px; border-radius: var(--radius-pill); background: var(--gv-track); overflow: hidden; box-shadow: inset 0 0 0 2px var(--line); }
.gv-slider__fill { position: absolute; inset: 0; display: flex; flex-direction: column; transform: translateX(calc(-100% + 15px + var(--p) * (100% - 30px))); border-radius: var(--radius-pill); }
.gv-slider__fill i { flex: 1; }
.gv-slider__fill i:nth-child(1) { background: var(--mustard); }
.gv-slider__fill i:nth-child(2) { background: var(--orange); }
.gv-slider__fill i:nth-child(3) { background: var(--rust); }
.gv-slider__input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.gv-slider__knob {
  position: absolute; top: 50%; left: calc(var(--p) * (100% - 30px)); width: 30px; height: 30px; margin-top: -15px;
  border-radius: 50%; background: var(--cream); border: 3px solid var(--chocolate); box-shadow: 0 3px 0 var(--chocolate);
  pointer-events: none; transition: transform var(--gv-t-press) var(--gv-squish);
}
.gv-slider__rail:hover .gv-slider__knob { transform: scale(1.08); }
.gv-slider__input:active ~ .gv-slider__knob { transform: scale(1.22, .84); transition: transform var(--gv-t-pop) var(--gv-boing); }
.gv-slider__input:focus-visible ~ .gv-slider__knob { outline: 3px solid var(--focus); outline-offset: 3px; }
.gv-slider__bubble {
  position: absolute; left: 50%; bottom: calc(100% + 10px); translate: -50% 0; padding: 7px 12px 5px; min-width: 40px; text-align: center;
  border-radius: 999px 999px 10px 10px; background: var(--gv-tip-bg); color: var(--gv-tip-fg);
  font: 400 15px/1 var(--font-display); white-space: nowrap;
  opacity: 0; transform: scale(.4) translateY(10px); transform-origin: 50% 100%;
  transition: opacity 140ms, transform var(--gv-t-pop) var(--gv-boing);
}
.gv-slider__input:active ~ .gv-slider__knob .gv-slider__bubble,
.gv-slider__input:focus-visible ~ .gv-slider__knob .gv-slider__bubble,
.gv-slider__rail:hover .gv-slider__bubble { opacity: 1; transform: scale(calc(1 / 1.08)); }
.gv-slider__input:active ~ .gv-slider__knob .gv-slider__bubble { transform: scale(.82, 1.19); }
.gv-slider__ends { display: flex; justify-content: space-between; font: 700 13px/18px var(--font-body); color: var(--gv-fg-soft); }
.gv-slider.is-disabled { opacity: .5; }

/* ==========================================================================
   Card: a rounded slab that wobbles into place; clickable ones show the stripe drop
   ========================================================================== */
.gv-card {
  position: relative; display: flex; flex-direction: column; min-width: 0;
  border: 0; padding: 0; margin: 0; font: inherit; text-align: left; text-decoration: none;
  border-radius: var(--radius-lg); background: var(--gv-fill); color: var(--gv-fg);
  box-shadow: var(--shadow-card);
}
[data-theme="dark"] .gv-card.gv-tone-face, [data-theme="dark"] .gv-card.gv-tone-chocolate { box-shadow: inset 0 0 0 1.5px var(--line), var(--shadow-card); }
.gv-card__stripes { border-radius: var(--radius-lg) var(--radius-lg) 0 0; overflow: hidden; }
.gv-card__body { display: flex; flex-direction: column; gap: 10px; padding: var(--space-6); min-width: 0; }
.gv-card--tight .gv-card__body { padding: var(--space-4); }
.gv-card__eyebrow { color: var(--gv-accent); }
.gv-card__title { display: block; margin: 0; font: 400 26px/30px var(--font-display); color: var(--gv-fg); }
.gv-card__text { margin: 0; color: var(--gv-fg-soft); }
.gv-card__foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding: 0 var(--space-6) var(--space-6); }
.gv-card--stack { box-shadow: var(--shadow-stack); margin-bottom: 18px; }
.gv-card--click { cursor: pointer; transition: translate 280ms var(--gv-groove), rotate 280ms var(--gv-groove), box-shadow 280ms var(--gv-groove); }
.gv-card--click::after { content: ""; position: absolute; inset: 0 -4px -22px 0; border-radius: inherit; z-index: -1; }
.gv-card--click:hover { translate: 0 -6px; rotate: -.6deg; box-shadow: var(--shadow-stack); }
.gv-card--click:active { translate: 0 2px; rotate: 0deg; box-shadow: var(--shadow-card); transition-duration: var(--gv-t-press); }

/* ==========================================================================
   Badge + Tag
   ========================================================================== */
.gv-badge {
  display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; flex: none;
  border-radius: var(--radius-pill); background: var(--gv-fill); color: var(--gv-fg);
  font: 800 11.5px/1 var(--font-body); letter-spacing: .12em; text-transform: uppercase; white-space: nowrap;
}
.gv-badge__dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.gv-tag {
  display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 16px; flex: none;
  border-radius: var(--radius-pill); border: 2px solid transparent;
  background: var(--gv-fill, var(--room-sunk)); color: var(--gv-fg, var(--ink));
  font: 700 15px/1 var(--font-body); white-space: nowrap; transition: transform 220ms var(--gv-groove), opacity 220ms, translate var(--gv-t-hover) var(--gv-groove), background-color var(--gv-t-hover), border-color var(--gv-t-hover);
}
.gv-tag:not([class*="gv-tone-"]) { --gv-fill: var(--room-sunk); color: var(--ink); }
.gv-tag--pick { cursor: pointer; background: transparent; border-color: var(--ink-soft); color: var(--gv-fg); }
.gv-tag--pick:hover { translate: 0 -2px; border-color: var(--gv-fg); }
.gv-tag--pick[aria-pressed="true"] { background: var(--mustard); border-color: var(--mustard); color: var(--chocolate); }
.gv-tag.is-boing { animation: gv-boing 440ms linear; }
.gv-tag.is-leaving { transform: scale(.4); opacity: 0; }
.gv-tag__x { display: grid; place-items: center; width: 24px; height: 24px; margin-right: -8px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: inherit; cursor: pointer; }
.gv-tag__x:hover { background: color-mix(in srgb, currentColor 15%, transparent); }
.gv-tag__x:focus-visible { outline: 2.5px solid var(--focus); outline-offset: 1px; }

/* ==========================================================================
   Avatar: initials in Bagel inside an organic blob
   ========================================================================== */
.gv-avatar {
  --s: 44px; position: relative; display: inline-grid; place-items: center; flex: none;
  width: var(--s); height: var(--s); background: var(--gv-fill); color: var(--gv-fg);
  font: 400 calc(var(--s) * .4)/1 var(--font-display);
}
.gv-avatar img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; display: block; }
.gv-avatar__txt { padding-top: .06em; }
.gv-avatar--sm { --s: 32px; } .gv-avatar--md { --s: 44px; } .gv-avatar--lg { --s: 64px; } .gv-avatar--xl { --s: 96px; }
.gv-avatar--ring { box-shadow: 0 0 0 3px var(--gv-ring, var(--room)); }
.gv-avatar--more { --gv-fill: var(--room-sunk); --gv-fg: var(--ink); font-size: calc(var(--s) * .34); }
.gv-avatar:hover { animation: gv-morph var(--gv-t-morph) ease-in-out infinite alternate; }
.gv-avatar__status { position: absolute; right: -1px; bottom: -1px; width: 28%; height: 28%; min-width: 10px; min-height: 10px; border-radius: 50%; box-shadow: 0 0 0 3px var(--room); }
.gv-avatar__status--on { background: var(--avocado); } .gv-avatar__status--away { background: var(--mustard); } .gv-avatar__status--off { background: var(--ink-soft); }
.gv-avstack { display: inline-flex; align-items: center; }
.gv-avstack > * + * { margin-left: -10px; }

/* ==========================================================================
   Tooltip: a rounded bubble with thought-bubble dots that pops on a boing
   ========================================================================== */
.gv-tipwrap { position: relative; display: inline-flex; }
.gv-tip {
  position: absolute; z-index: 60; left: 50%; bottom: calc(100% + 16px); translate: -50% 0;
  width: max-content; max-width: 240px; padding: 9px 15px; border-radius: var(--radius-md);
  background: var(--gv-tip-bg); color: var(--gv-tip-fg); box-shadow: var(--shadow-float);
  font: 700 14px/20px var(--font-body); text-align: center; pointer-events: none;
  opacity: 0; transform: scale(.5) translateY(8px); transform-origin: 50% 100%;
  transition: opacity 140ms, transform var(--gv-t-pop) var(--gv-boing);
}
.gv-tip::before, .gv-tip::after { content: ""; position: absolute; left: 50%; border-radius: 50%; background: var(--gv-tip-bg); }
.gv-tip::before { width: 10px; height: 10px; bottom: -8px; margin-left: -5px; }
.gv-tip::after { width: 6px; height: 6px; bottom: -15px; margin-left: -1px; }
.gv-tip--bottom { bottom: auto; top: calc(100% + 16px); transform-origin: 50% 0; transform: scale(.5) translateY(-8px); }
.gv-tip--bottom::before { bottom: auto; top: -8px; }
.gv-tip--bottom::after { bottom: auto; top: -15px; }
.gv-tipwrap.is-open .gv-tip { opacity: 1; transform: none; }

/* ==========================================================================
   Toast: boings up from the corner, stripes along its hem
   ========================================================================== */
.gv-toasts { position: fixed; z-index: 100; right: 24px; bottom: 24px; display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-3); width: min(400px, calc(100vw - 32px)); pointer-events: none; }
.gv-toast {
  position: relative; display: flex; align-items: center; gap: var(--space-3); width: 100%;
  padding: 14px 12px 22px 14px; border-radius: 22px; overflow: hidden; pointer-events: auto;
  background: var(--gv-fill); color: var(--gv-fg); box-shadow: var(--shadow-float);
  animation: gv-toast-in 560ms var(--gv-wobble) backwards;
  transition: transform 300ms var(--gv-exit), opacity 300ms var(--gv-exit);
}
[data-theme="dark"] .gv-toast.gv-tone-chocolate { box-shadow: inset 0 0 0 1.5px var(--line), var(--shadow-float); }
.gv-toast.is-leaving { opacity: 0; transform: translateX(110%) rotate(6deg); }
.gv-toast__icon { flex: none; display: grid; place-items: center; width: 42px; height: 42px; background: var(--mustard); color: var(--chocolate); }
.gv-tone-mustard .gv-toast__icon, .gv-tone-orange .gv-toast__icon, .gv-tone-avocado .gv-toast__icon, .gv-tone-rust .gv-toast__icon { background: var(--cream); }
.gv-toast__body { flex: 1; min-width: 0; }
.gv-toast__title { font: 800 16px/22px var(--font-body); }
.gv-toast__msg { font: 600 14px/20px var(--font-body); color: var(--gv-fg-soft); }
.gv-toast__action { flex: none; height: 34px; padding: 0 14px; border-radius: 999px; border: 2px solid currentColor; background: transparent; color: inherit; font: 400 14px/1 var(--font-display); cursor: pointer; }
.gv-toast__action:hover { background: color-mix(in srgb, currentColor 14%, transparent); }
.gv-toast__x { flex: none; display: grid; place-items: center; width: 34px; height: 34px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: inherit; cursor: pointer; }
.gv-toast__x:hover { background: color-mix(in srgb, currentColor 14%, transparent); }
.gv-toast__stripes { position: absolute; left: 0; right: 0; bottom: 0; height: 9px; display: flex; flex-direction: column; }
.gv-toast__stripes i { flex: 1; }
.gv-toast__stripes i:nth-child(1) { background: var(--mustard); }
.gv-toast__stripes i:nth-child(2) { background: var(--orange); }
.gv-toast__stripes i:nth-child(3) { background: var(--rust); }
.gv-tone-mustard .gv-toast__stripes i:nth-child(1), .gv-tone-orange .gv-toast__stripes i:nth-child(2) { background: var(--cream); }
.gv-tone-rust .gv-toast__stripes i:nth-child(3) { background: var(--chocolate); }
@media (max-width: 520px) { .gv-toasts { left: 16px; right: 16px; bottom: 16px; width: auto; align-items: stretch; } }

/* ==========================================================================
   Modal: a rising arch over a rounded slab that wobbles in on a flat scrim
   ========================================================================== */
.gv-modal { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; padding: var(--space-4); }
.gv-modal[hidden] { display: none; }
.gv-modal__scrim { position: absolute; inset: 0; background: var(--scrim); transition: opacity 260ms; }
.gv-modal__panel {
  position: relative; width: min(520px, 100%); max-height: calc(100vh - 32px); overflow: auto;
  padding: 0 var(--space-8) var(--space-8); border-radius: var(--radius-xl) var(--radius-xl) var(--radius-lg) var(--radius-lg);
  background: var(--face); color: var(--ink); box-shadow: var(--shadow-float); outline: none;
  --gv-fg: var(--ink); --gv-fg-soft: var(--ink-soft);
  transition: transform 260ms var(--gv-exit), opacity 260ms var(--gv-exit);
}
.gv-modal__panel--sm { width: min(420px, 100%); }
.gv-modal.is-in .gv-modal__scrim { animation: gv-fade 260ms ease-out backwards; }
.gv-modal.is-in .gv-modal__panel { animation: gv-modal-in 680ms cubic-bezier(.25, .8, .4, 1) backwards; }
.gv-modal.is-leaving .gv-modal__scrim { opacity: 0; }
.gv-modal.is-leaving .gv-modal__panel { opacity: 0; transform: translateY(48px) rotate(2deg) scale(.95); }
.gv-modal__arch { display: flex; justify-content: center; padding-top: var(--space-6); }
.gv-modal__sg { width: 220px; height: 110px; }
.gv-modal__x { position: absolute; top: 16px; right: 16px; }
.gv-modal__head { text-align: center; margin-top: var(--space-4); }
.gv-modal__eyebrow { color: var(--accent-text); margin-bottom: 6px; }
.gv-modal__title { margin: 0; font: 400 34px/38px var(--font-display); }
.gv-modal__body { margin-top: var(--space-3); color: var(--ink); }
.gv-modal__body > p { margin: 0 0 var(--space-3); color: var(--ink-soft); text-align: center; }
.gv-modal__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-3); margin-top: var(--space-6); }
@media (max-width: 520px) { .gv-modal__panel { padding: 0 var(--space-4) var(--space-6); } .gv-modal__title { font-size: 28px; line-height: 32px; } }

/* ==========================================================================
   Progress: a three-band stripe glides along a pill
   ========================================================================== */
.gv-progress { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.gv-progress__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.gv-progress__label { font: 700 15px/20px var(--font-body); color: var(--gv-fg); }
.gv-progress__val { font: 400 18px/20px var(--font-display); color: var(--gv-fg); font-variant-numeric: tabular-nums; }
.gv-progress__track { position: relative; height: 18px; border-radius: var(--radius-pill); background: var(--gv-track); overflow: hidden; }
.gv-progress__fill { position: absolute; inset: 0; display: flex; flex-direction: column; border-radius: var(--radius-pill); transform: translateX(calc((var(--p, 0) - 1) * 100%)); transition: transform 1100ms var(--gv-groove); }
.gv-progress__fill i { flex: 1; }
.gv-progress__fill i:nth-child(1) { background: var(--mustard); }
.gv-progress__fill i:nth-child(2) { background: var(--orange); }
.gv-progress__fill i:nth-child(3) { background: var(--rust); }
.gv-progress--sm .gv-progress__track { height: 10px; }
.gv-progress__track.is-indeterminate .gv-progress__fill { right: auto; width: 38%; animation: gv-indet 1500ms var(--gv-groove) infinite; transition: none; }

/* ==========================================================================
   Record: the vinyl loading spinner (33⅓ rpm: one turn every 1.8s)
   ========================================================================== */
.gv-record { --size: 48px; display: inline-block; flex: none; width: var(--size); height: var(--size); vertical-align: middle; line-height: 0; }
.gv-record__svg { display: block; width: 100%; height: 100%; }
.gv-record__vinyl { fill: var(--chocolate); stroke: #fff3dc33; stroke-width: 1.2; }
[data-theme="dark"] .gv-record__vinyl { fill: #140b06; stroke: #fff3dc40; }
.gv-record__groove { fill: none; stroke: var(--cream); stroke-opacity: .16; stroke-width: .9; }
.gv-record__l1 { fill: var(--orange); } .gv-record__l2 { fill: var(--mustard); } .gv-record__l3 { fill: var(--rust); }
.gv-record__hole { fill: var(--cream); }
.gv-record__sheen { fill: var(--cream); opacity: .1; }
.gv-record__disc { transform-box: view-box; transform-origin: 50% 50%; }
.gv-record.is-spinning .gv-record__disc { animation: gv-spin var(--gv-t-spin) linear infinite; }

/* ==========================================================================
   Supergraphic: crisp flat bands — stripes, swooshes, arches, corners
   ========================================================================== */
.gv-sg { position: relative; display: block; width: 100%; height: 160px; overflow: hidden; pointer-events: none; }
.gv-sg svg { display: block; width: 100%; height: 100%; }
.gv-sg path.gv-sg__band { fill: none; }
.gv-sg--stripe { display: flex; flex-direction: column; height: 48px; }
.gv-sg--stripe .gv-sg__band { flex: 1; display: block; }
.gv-sg--arch, .gv-sg--corner { height: auto; aspect-ratio: auto; }
.gv-sg--arch svg { height: 100%; }
.gv-sg--swoosh path.gv-sg__band { transform-box: fill-box; }
.gv-sg--arch path.gv-sg__band, .gv-sg--corner path.gv-sg__band { transform-box: view-box; transform-origin: 50% 100%; }
.gv-sg--corner path.gv-sg__band { transform-origin: 0 100%; }
.gv-sg--armed:not(.is-in) .gv-sg__band { opacity: 0; }
.gv-sg--armed.is-in .gv-sg__band { animation: gv-swoosh var(--gv-t-swoosh) var(--gv-groove) backwards; animation-delay: calc(var(--i, 0) * 90ms); }
.gv-sg--armed.is-in.gv-sg--arch .gv-sg__band, .gv-sg--armed.is-in.gv-sg--corner .gv-sg__band { animation-name: gv-arch-up; animation-timing-function: var(--gv-boing); animation-duration: 760ms; animation-delay: calc(var(--i, 0) * 80ms); }

/* ==========================================================================
   Blob: an organic shape that morphs only while you hover it (lava lamp optional)
   ========================================================================== */
.gv-blob {
  --size: 120px; position: relative; display: inline-grid; place-items: center; flex: none;
  width: var(--size); height: var(--size); padding: 0; border: 0; overflow: hidden; isolation: isolate;
  background: var(--gv-fill); color: var(--gv-fg); font: 400 calc(var(--size) * .2)/1 var(--font-display);
  transition: rotate 500ms var(--gv-boing), scale 500ms var(--gv-boing);
}
button.gv-blob { cursor: pointer; }
.gv-blob:hover { animation: gv-morph var(--gv-t-morph) ease-in-out infinite alternate; rotate: -7deg; scale: 1.04; }
.gv-blob.is-boing { animation: gv-boing 480ms linear; }
.gv-blob__in { position: relative; z-index: 1; display: grid; place-items: center; text-align: center; transition: rotate 500ms var(--gv-boing); }
.gv-blob:hover .gv-blob__in { rotate: 7deg; }
.gv-blob__lava { position: absolute; inset: 0; z-index: 0; }
.gv-blob__lava i { position: absolute; display: block; border-radius: 55% 45% 50% 50% / 50% 55% 45% 50%; transition: translate 1.8s var(--gv-groove); }
.gv-blob__lava i:nth-child(1) { width: 40%; height: 36%; left: 10%; bottom: -12%; background: var(--mustard); }
.gv-blob__lava i:nth-child(2) { width: 26%; height: 24%; left: 58%; bottom: 4%; background: var(--rust); transition-delay: 120ms; }
.gv-blob__lava i:nth-child(3) { width: 18%; height: 18%; left: 38%; bottom: -8%; background: var(--cream); transition-delay: 260ms; }
.gv-tone-mustard .gv-blob__lava i:nth-child(1) { background: var(--orange); }
.gv-tone-rust .gv-blob__lava i:nth-child(2), .gv-tone-chocolate .gv-blob__lava i:nth-child(2) { background: var(--orange); }
.gv-blob--lava:hover .gv-blob__lava i { animation: gv-morph 1.2s ease-in-out infinite alternate; }
.gv-blob--lava:hover .gv-blob__lava i:nth-child(1) { translate: 8% -150%; }
.gv-blob--lava:hover .gv-blob__lava i:nth-child(2) { translate: -30% -230%; }
.gv-blob--lava:hover .gv-blob__lava i:nth-child(3) { translate: 40% -380%; }

/* ==========================================================================
   RainbowArc: concentric bands rotate up into a semicircle (transform only)
   ========================================================================== */
.gv-arc { --size: 240px; position: relative; display: inline-flex; flex-direction: column; align-items: center; width: var(--size); max-width: 100%; margin: 0; }
.gv-arc__dial { position: relative; width: 100%; aspect-ratio: 2 / 1; overflow: hidden; }
.gv-arc__track, .gv-arc__fill { position: absolute; left: 0; top: 0; width: 100%; display: block; }
.gv-arc__track { height: 100%; }
.gv-arc__fill { height: 200%; }
.gv-arc__track path { fill: none; stroke: var(--gv-track); }
.gv-arc__fill path { fill: none; }
.gv-arc__band { transform-box: view-box; transform-origin: 50% 50%; transform: rotate(var(--a)); transition: transform 1300ms var(--gv-wobble) calc(var(--i) * 90ms); }
.gv-arc__readout { position: absolute; left: 0; right: 0; top: 0; aspect-ratio: 2 / 1; display: flex; align-items: flex-end; justify-content: center; gap: 2px; pointer-events: none; }
.gv-arc__num { font: 400 calc(var(--size) * .2)/.8 var(--font-display); color: var(--gv-fg); font-variant-numeric: tabular-nums; }
.gv-arc__unit { font: 400 calc(var(--size) * .085)/1 var(--font-display); color: var(--gv-fg-soft); padding-bottom: 2px; }
.gv-arc__ends { display: flex; justify-content: space-between; width: 100%; padding: 4px 3% 0; font: 800 12px/16px var(--font-body); color: var(--gv-fg-soft); letter-spacing: .06em; }
.gv-arc__cap { display: flex; flex-direction: column; align-items: center; text-align: center; margin-top: var(--space-2); }
.gv-arc__label { font: 800 15px/20px var(--font-body); color: var(--gv-fg); }
.gv-arc__sub { font: 600 14px/20px var(--font-body); color: var(--gv-fg-soft); }

/* ==========================================================================
   Widget: NowPlaying
   ========================================================================== */
.gv-np { overflow: hidden; }
.gv-np { display: grid; grid-template-columns: 158px minmax(0, 1fr); gap: var(--space-6); align-items: center; padding: var(--space-6); }
.gv-np__deck { position: relative; width: 158px; height: 158px; }
.gv-np__platter { position: absolute; inset: 0; border-radius: 50%; background: var(--rust); box-shadow: inset 0 0 0 8px var(--orange), inset 0 0 0 16px var(--mustard); }
.gv-np__record { position: absolute; left: 13px; top: 13px; }
.gv-np__arm { position: absolute; right: -16px; top: -10px; transform-origin: 28px 12px; rotate: 28deg; transition: rotate 760ms var(--gv-boing); }
.gv-np.is-playing .gv-np__arm { rotate: 0deg; }
.gv-np__pivot { fill: var(--mustard); }
.gv-np__rod { fill: none; stroke: var(--cream); stroke-width: 4.5; stroke-linecap: round; stroke-linejoin: round; }
.gv-np__head { fill: var(--cream); }
.gv-np__info { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.gv-np__top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; }
.gv-np__like { margin-right: -8px; }
.gv-np__title { font: 400 26px/30px var(--font-display); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gv-np__title.is-in { animation: gv-rise 420ms var(--gv-groove); }
.gv-np__artist { font: 600 15px/20px var(--font-body); color: var(--gv-fg-soft); }
.gv-np__time { margin-top: 10px; }
.gv-np__prog { position: relative; height: 9px; border-radius: 999px; background: var(--gv-track); overflow: hidden; }
.gv-np__fill { position: absolute; inset: 0; display: flex; flex-direction: column; border-radius: 999px; transform: translateX(calc((var(--p, 0) - 1) * 100%)); transition: transform 1s linear; }
.gv-np__fill i { flex: 1; }
.gv-np__fill i:nth-child(1) { background: var(--mustard); } .gv-np__fill i:nth-child(2) { background: var(--orange); } .gv-np__fill i:nth-child(3) { background: var(--rust); }
.gv-np__nums { display: flex; justify-content: space-between; margin-top: 4px; font: 700 13px/18px var(--font-body); color: var(--gv-fg-soft); font-variant-numeric: tabular-nums; }
.gv-np__ctrl { display: flex; align-items: center; gap: var(--space-3); margin-top: 6px; }
@media (max-width: 460px) {
  .gv-np { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center; padding: var(--space-6) var(--space-4); }
  .gv-np__info { width: 100%; }
  .gv-np__ctrl { justify-content: center; }
}

/* ==========================================================================
   Widget: EventTicket
   ========================================================================== */
.gv-ticket {
  position: relative; display: grid; grid-template-columns: 104px minmax(0, 1fr); min-width: 0;
  border-radius: var(--radius-lg); background: var(--face); color: var(--ink); box-shadow: var(--shadow-card);
  --gv-fg: var(--ink); --gv-fg-soft: var(--ink-soft);
  transition: translate 280ms var(--gv-groove), rotate 280ms var(--gv-groove);
}
[data-theme="dark"] .gv-ticket { box-shadow: inset 0 0 0 1.5px var(--line), var(--shadow-card); }
.gv-ticket::after { content: ""; position: absolute; inset: 0 -4px -12px 0; border-radius: inherit; z-index: -1; }
.gv-ticket:hover { translate: 0 -5px; rotate: -.5deg; }
.gv-ticket__stub {
  position: relative; display: flex; flex-direction: column; align-items: center; padding: 18px 8px 56px; overflow: hidden;
  border-radius: var(--radius-lg) 0 0 var(--radius-lg); background: var(--gv-fill); color: var(--gv-fg); text-align: center;
  transition: background-color 300ms;
}
.gv-ticket.is-going .gv-ticket__stub { background: var(--avocado); }
.gv-ticket__dow, .gv-ticket__mon { position: relative; z-index: 1; font: 800 12px/16px var(--font-body); letter-spacing: .14em; text-transform: uppercase; }
.gv-ticket__day { position: relative; z-index: 1; font: 400 46px/48px var(--font-display); }
.gv-ticket__sg { position: absolute; left: 0; bottom: 0; width: 76px; height: 76px; }
.gv-ticket__sg .gv-sg { height: 100%; }
.gv-ticket__main { position: relative; display: flex; flex-direction: column; gap: 6px; padding: 16px 18px 16px 22px; min-width: 0; }
.gv-ticket__main::before { content: ""; position: absolute; left: -3px; top: 16px; bottom: 16px; width: 6px; background-image: radial-gradient(circle, var(--line) 2.2px, transparent 2.7px); background-size: 6px 11px; background-position: center top; }
.gv-ticket__tags { display: flex; flex-wrap: wrap; gap: 6px; }
.gv-ticket__title { margin: 2px 0 0; font: 400 22px/26px var(--font-display); }
.gv-ticket__meta { display: flex; flex-wrap: wrap; gap: 4px 14px; font: 600 14px/20px var(--font-body); color: var(--ink-soft); }
.gv-ticket__meta span { display: inline-flex; align-items: center; gap: 5px; }
.gv-ticket__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: auto; padding-top: 8px; flex-wrap: wrap; }
.gv-ticket__price { font: 400 20px/24px var(--font-display); color: var(--accent-text); }
/* the punched notches where the stub tears off */
.gv-ticket { --gv-notch-c: var(--gv-notch); }
.gv-ticket::before { content: ""; position: absolute; left: 93px; top: -11px; width: 22px; height: calc(100% + 22px); pointer-events: none; z-index: 2;
  background: radial-gradient(circle at 11px 11px, var(--gv-notch-c) 10.5px, transparent 11px) top / 22px 22px no-repeat, radial-gradient(circle at 11px 11px, var(--gv-notch-c) 10.5px, transparent 11px) bottom / 22px 22px no-repeat; }
@media (max-width: 400px) {
  .gv-ticket { grid-template-columns: 84px minmax(0, 1fr); }
  .gv-ticket::before { left: 73px; }
  .gv-ticket__day { font-size: 38px; line-height: 42px; }
  .gv-ticket__sg { width: 60px; height: 60px; }
}

/* ==========================================================================
   Widget: Setlist
   ========================================================================== */
.gv-setlist__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.gv-setlist__body { position: relative; margin-top: 4px; }
.gv-setlist__rail { position: absolute; top: 22px; bottom: 22px; left: 74px; width: 9px; display: flex; }
.gv-setlist__rail i { flex: 1; }
.gv-setlist__rail i:nth-child(1) { background: var(--mustard); } .gv-setlist__rail i:nth-child(2) { background: var(--orange); } .gv-setlist__rail i:nth-child(3) { background: var(--rust); }
.gv-setlist__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.gv-setlist__item { display: grid; grid-template-columns: 50px 30px minmax(0, 1fr) auto; align-items: center; gap: 12px; padding: 9px 12px; margin: 0 -12px; border-radius: 18px; }
.gv-setlist__item.is-live { background: var(--room-sunk); }
.gv-setlist__time { font: 800 14px/20px var(--font-body); color: var(--gv-fg-soft); font-variant-numeric: tabular-nums; }
.gv-setlist__node { position: relative; z-index: 1; display: grid; place-items: center; width: 26px; height: 26px; margin-left: 2px; border-radius: 50%; background: var(--gv-fill); border: 3px solid var(--ink-soft); }
.gv-setlist__item.is-played .gv-setlist__node { background: var(--rust); border-color: var(--rust); }
.gv-setlist__item.is-live .gv-setlist__node { border: 0; background: none; }
.gv-setlist__what { display: flex; flex-direction: column; min-width: 0; }
.gv-setlist__what b { font: 800 16px/22px var(--font-body); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gv-setlist__what span { font: 600 14px/20px var(--font-body); color: var(--gv-fg-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gv-setlist__item.is-played .gv-setlist__what b { color: var(--gv-fg-soft); }
.gv-setlist__done { color: var(--ok-text); display: inline-flex; }

/* ==========================================================================
   Widget: ArcStat
   ========================================================================== */
.gv-arcstat__head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.gv-arcstat__arc { display: flex; justify-content: center; padding-top: var(--space-4); }
.gv-arcstat__delta { display: inline-flex; align-items: center; justify-content: center; gap: 4px; align-self: center; font: 800 14px/20px var(--font-body); }
.gv-arcstat__delta.is-up { color: var(--ok-text); }
.gv-arcstat__delta.is-down { color: var(--error); }
.gv-tone-chocolate .gv-arcstat__delta.is-up { color: var(--avocado); }

/* ==========================================================================
   Reduced motion: no travel, no spin, no morph — states still change
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-delay: 0ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; transition-delay: 0ms !important; }
  .gv-record.is-spinning .gv-record__disc { animation: none !important; }
  .gv-blob:hover, .gv-avatar:hover { animation: none !important; rotate: none; scale: none; }
}
