/* Harvest to Horizon game skin: Animal Crossing soft pastel (owner, 3 Nov 2026; planner 6c0d237b). Designed by Codex in
   /tmp/h2h-skin (BRIEF.md, NOTES.md v1-v3), approved by the owner. Loaded by index.html at the END of <body> so it follows
   every stylesheet the HUD and lazy sheets inject into <head> (equal specificity: the skin wins). Visual layer only: the
   kit (src/ui/kit.ts) still owns markup, kinds and behaviour. Not part of the JS bundle (the main chunk does not grow). */
/* Harvest to Horizon · soft pastel skin
   Load AFTER village-hud.css, the remaining HUD CSS, and both installed kit styles.
   The skin owns spacing, type and desktop caps. Sheet/HUD anchors and safe-area owners stay intact. */
:root {
  --vg-skin-cream: #fff9ed;
  --vg-skin-paper: #fffdf7;
  --vg-skin-rim: #dfd1b8;
  --vg-skin-ink: #514336;
  --vg-skin-ink-soft: #6f6054;
  --vg-skin-mint: #bfe3cc;
  --vg-skin-mint-lip: #8aaf95;
  --vg-skin-green: #c4e7b4;
  --vg-skin-green-lip: #8bb57c;
  --vg-skin-green-ink: #31583b;
  --vg-skin-peach: #f7d9b4;
  --vg-skin-peach-lip: #c9aa87;
  --vg-skin-lilac: #ebe3f3;
  --vg-skin-lilac-lip: #b4a2c4;
  --vg-skin-lilac-ink: #5b456e;
  --vg-skin-sky: #d3e7ef;
  --vg-skin-sky-lip: #9dbbc7;
  --vg-skin-sky-ink: #34586a;
  --vg-skin-butter: #f8e7a9;
  --vg-skin-butter-lip: #c8b271;
  --vg-skin-butter-ink: #665126;
  --vg-skin-rose: #f5c9c1;
  --vg-skin-rose-lip: #c18a80;
  --vg-skin-rose-ink: #8a3936;
  --vg-skin-muted: #eee7da;
  --vg-skin-muted-lip: #d0c6b3;
  --vg-skin-muted-ink: #726451;
  --vg-skin-focus: #32645c;
  --vg-skin-switch-off: #93826c;
  --vg-skin-switch-on: #527e61;
  --vg-skin-highlight: #ffffff99;
  --vg-skin-shadow: #51433616;
  --vg-skin-backdrop: #263f394d;
  --vg-skin-font-body-family: 'Nunito', 'Avenir Next Rounded', 'SF Pro Rounded', ui-rounded, system-ui, sans-serif;
  --vg-skin-font-display-family: 'VG Skin Lilita', 'Nunito', 'Avenir Next Rounded', 'SF Pro Rounded', ui-rounded, system-ui, sans-serif;
  /* Physical spacing stays in px; text and control heights can grow independently. */
  --vg-skin-space-0: 0px;
  --vg-skin-space-2xs: 2px;
  --vg-skin-space-xs: 4px;
  --vg-skin-space-sm: 8px;
  --vg-skin-space-md: 12px;
  --vg-skin-space-lg: 16px;
  --vg-skin-space-xl: 24px;
  --vg-skin-space-2xl: 32px;

  /* Do not set html's font-size or multiply a second text-scale setting. */
  --vg-skin-font-title: 1.375rem;
  --vg-skin-font-heading: 1.125rem;
  --vg-skin-font-label: 1rem;
  --vg-skin-font-body: 1rem;
  --vg-skin-font-small: .875rem;
  --vg-skin-font-counter: .8125rem;
  --vg-skin-font-counter-wide: .6875rem;
  --vg-skin-font-dock: .75rem;
  --vg-skin-font-icon: 1.5rem;
  --vg-skin-font-display-weight: 400;
  --vg-skin-font-body-weight: 500;
  --vg-skin-font-small-weight: 600;
  --vg-skin-font-strong-weight: 700;
  --vg-skin-font-title-line: 1.15;
  --vg-skin-font-heading-line: 1.25;
  --vg-skin-font-label-line: 1.2;
  --vg-skin-font-body-line: 1.5;
  --vg-skin-font-small-line: 1.4;
  --vg-skin-font-display-tracking: .01em;
  --vg-skin-font-body-tracking: 0em;

  --vg-skin-lip: 4px;
  --vg-skin-pressed-shadow: inset 0 2px 0 var(--vg-skin-highlight);

  /* Existing game vocabulary stays useful outside kit controls, too. */
  --vg-cream: var(--vg-skin-cream);
  --vg-cream-border: var(--vg-skin-rim);
  --vg-panel: var(--vg-skin-cream);
  --vg-ink: var(--vg-skin-ink);
  --vg-ink-soft: var(--vg-skin-ink-soft);
  --vg-rim: var(--vg-skin-rim);
  --vg-sage: var(--vg-skin-green);
  --vg-sage-ring: var(--vg-skin-green-lip);
  --vg-sky: var(--vg-skin-sky);
  --vg-gold: var(--vg-skin-butter-lip);
  --vg-orange: var(--vg-skin-peach);
  --vg-orange-deep: var(--vg-skin-peach-lip);
  --vg-danger: var(--vg-skin-rose-ink);
  --vg-focus: var(--vg-skin-focus);
  --vg-shadow: var(--vg-skin-shadow);
  --vg-raised: inset 0 2px 0 var(--vg-skin-highlight), 0 4px 0 var(--vg-skin-rim);
  --vg-gap-xs: var(--vg-skin-space-xs);
  --vg-gap-sm: var(--vg-skin-space-sm);
  --vg-gap-md: var(--vg-skin-space-md);
  --vg-gap-lg: var(--vg-skin-space-lg);
  --vg-gap-xl: var(--vg-skin-space-xl);
  --vg-pad-sheet: var(--vg-skin-space-lg);
  --vg-pad-card: var(--vg-skin-space-lg);
  --vg-pad-chip: var(--vg-skin-space-sm);
  --vg-k-gap: var(--vg-skin-space-sm);
  --vg-k-gap-lg: var(--vg-skin-space-lg);
  --vg-k-pad-y: var(--vg-skin-space-md);
  --vg-k-pad-x: var(--vg-skin-space-lg); /* v3.2: 32 -> 16 px ends (kit-fit probe; see NOTES) */
  --vg-k-h: 48px;
  --vg-r-panel: 32px;
  --vg-r-card: 20px;
}

@font-face {
  font-family: 'VG Skin Lilita';
  src: url('./fonts/LilitaOne-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

body, #app, .vg-dialog-content.vg-dialog-content {
  font-family: var(--vg-skin-font-body-family);
  color: var(--vg-skin-ink);
  line-height: 1.5;
}

/* A control's hue owns its lip. Layout ownership stays with the kit. */
.vg-k-btn {
  --vg-skin-fill: var(--vg-skin-peach);
  --vg-skin-edge: var(--vg-skin-peach-lip);
  --vg-skin-label: var(--vg-skin-ink);
}
.vg-k-btn.vg-k-primary, .vg-k-btn.vg-k-tone-green, .vg-k-btn.vg-k-hud-plus {
  --vg-skin-fill: var(--vg-skin-green);
  --vg-skin-edge: var(--vg-skin-green-lip);
  --vg-skin-label: var(--vg-skin-green-ink);
}
.vg-k-btn.vg-k-danger {
  --vg-skin-fill: var(--vg-skin-rose);
  --vg-skin-edge: var(--vg-skin-rose-lip);
  --vg-skin-label: var(--vg-skin-rose-ink);
}
.vg-k-btn.vg-k-quiet {
  --vg-skin-fill: var(--vg-skin-lilac);
  --vg-skin-edge: var(--vg-skin-lilac-lip);
  --vg-skin-label: var(--vg-skin-lilac-ink);
}
.vg-k-btn.vg-k-chip, .vg-k-btn.vg-k-hud-portrait {
  --vg-skin-fill: var(--vg-skin-sky);
  --vg-skin-edge: var(--vg-skin-sky-lip);
  --vg-skin-label: var(--vg-skin-sky-ink);
}
.vg-k-btn.vg-k-tone-gold {
  --vg-skin-fill: var(--vg-skin-butter);
  --vg-skin-edge: var(--vg-skin-butter-lip);
  --vg-skin-label: var(--vg-skin-butter-ink);
}
.vg-k-btn.vg-k-tone-cream {
  --vg-skin-fill: var(--vg-skin-paper);
  --vg-skin-edge: var(--vg-skin-rim);
}
.vg-k-btn[aria-pressed="true"], .vg-k-tabs > .vg-k-btn[aria-selected="true"],
#vg-panel-body .vg-town-tab[aria-pressed="true"] {
  --vg-skin-fill: var(--vg-skin-mint);
  --vg-skin-edge: var(--vg-skin-mint-lip);
  --vg-skin-label: var(--vg-skin-green-ink);
}
.vg-k-btn.vg-k-btn,
.vg-k-btn.vg-k-primary.vg-dialog-primary,
.vg-k-btn.vg-k-hud.vg-k-tone-green,
.vg-k-btn.vg-k-hud.vg-k-tone-gold,
.vg-k-btn.vg-k-hud.vg-k-tone-cream,
#vg-panel-body .vg-town-tab,
#vg-dock .vg-k-btn.vg-k-hud-dock,
#vg-right .vg-k-btn.vg-k-hud-rail,
#vg-avatar.vg-k-hud-portrait,
#vg-next.vg-k-hud-cta,
#vg-collect.vg-k-hud-cta {
  border-color: var(--vg-skin-fill);
  border-radius: 999px;
  background: var(--vg-skin-fill);
  color: var(--vg-skin-label);
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 var(--vg-skin-lip) 0 var(--vg-skin-edge);
  font-family: var(--vg-skin-font-display-family);
  font-weight: var(--vg-skin-font-display-weight);
  font-synthesis: none;
  text-decoration: none;
  transition: transform 80ms ease-out, background-color 120ms ease-out;
}
.vg-k-btn.vg-k-tile { border-radius: var(--vg-r-card); }
.vg-k-btn.vg-k-icon, .vg-k-btn.vg-k-fab { border-radius: 50%; }
.vg-k-btn > .vg-k-sub {
  font-family: var(--vg-skin-font-body-family);
  color: var(--vg-skin-label);
  opacity: 1;
}

/* Quiet actions are padded capsules; v2 spacing is applied below. */
.vg-k-btn.vg-k-quiet {
  padding-inline: var(--vg-gap-md,12px);
  text-decoration: none;
  vertical-align: middle;
}
.vg-k-status .vg-k-btn.vg-k-quiet { vertical-align: middle; }

/* The upstream HUD declares these properties !important; match only those. */
.vg-k-btn.vg-k-hud:is(.vg-k-hud-dock,.vg-k-hud-rail,.vg-k-hud-pill,.vg-k-hud-cta,.vg-k-hud-chip,.vg-k-hud-fold,.vg-k-hud-portrait,.vg-k-hud-plus) {
  font-weight: var(--vg-skin-font-display-weight) !important;
}
.vg-k-btn.vg-k-chip,
.vg-k-btn.vg-k-hud:is(.vg-k-hud-pill,.vg-k-hud-chip,.vg-k-hud-fold),
.vg-k-btn.vg-k-hud-rail.vg-k-hud-menu {
  min-height: 48px !important;
}
.vg-k-btn.vg-k-hud-portrait { min-height: 48px; }
body.vg-street-mode .vg-k-btn.vg-k-hud:is(.vg-k-hud-chip,.vg-k-hud-cta) {
  min-height: 48px !important;
}

/* The dock is one cream tray; only the current tool is mint. */
.vg-k-btn.vg-k-hud-dock {
  --vg-skin-lip: 2px;
  --vg-skin-fill: transparent;
  --vg-skin-edge: transparent;
}
#vg-dock .vg-k-btn.vg-k-hud-dock { box-shadow: none; }
#vg-dock .vg-k-btn.vg-k-hud-dock.is-on {
  --vg-skin-fill: var(--vg-skin-mint);
  --vg-skin-edge: var(--vg-skin-mint-lip);
  --vg-skin-label: var(--vg-skin-green-ink);
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 var(--vg-skin-lip) 0 var(--vg-skin-edge);
}
.vg-k-btn.vg-k-hud-fold { --vg-skin-fill: transparent; --vg-skin-edge: transparent; box-shadow: none; }
.vg-k-btn.vg-k-hud-pill .vg-resource-icon { background: var(--vg-skin-butter); box-shadow: none; }
.vg-k-btn.vg-k-hud-pill[title="Gems"] .vg-resource-icon { background: var(--vg-skin-lilac); }
.vg-k-btn.vg-k-hud-pill[title="Energy"] .vg-resource-icon { background: var(--vg-skin-green); }
.vg-k-btn.vg-k-hud-rail small { color: inherit; font-weight: var(--vg-skin-font-display-weight); }
.vg-k-btn.vg-k-hud-dock .vg-dock-label { font-weight: var(--vg-skin-font-display-weight); }
@media (max-width:960px) {
  .vg-k-btn.vg-k-hud-pill { --vg-skin-fill: transparent; --vg-skin-edge: transparent; box-shadow: none; }
}

/* A selected tab stays raised; only physical :active sinks. */
@media (hover:hover) and (pointer:fine) {
  .vg-k-btn.vg-k-btn:hover:where(:not(:disabled):not([aria-disabled="true"])),
  .vg-k-btn.vg-k-btn:hover:not(:disabled):not(.vg-k-primary):not(.vg-k-danger):not(.vg-k-quiet):where(:not(.vg-k-hud):not([aria-disabled="true"])),
  #vg-dock .vg-k-btn.vg-k-hud-dock:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-right .vg-k-btn.vg-k-hud-rail:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-avatar.vg-k-hud-portrait:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-next.vg-k-hud-cta:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-collect.vg-k-hud-cta:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-panel-body .vg-town-tab:hover:where(:not(:disabled):not([aria-disabled="true"])) {
    background: color-mix(in srgb, var(--vg-skin-fill), var(--vg-skin-paper) 18%);
  }
  #vg-dock .vg-k-btn.vg-k-hud-dock:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-right .vg-k-btn.vg-k-hud-rail:hover:where(:not(:disabled):not([aria-disabled="true"])) { transform: none; }
}
.vg-k-btn.vg-k-btn:active:where(:not(:disabled):not([aria-disabled="true"])),
#vg-dock .vg-k-btn.vg-k-hud-dock:active:where(:not(:disabled):not([aria-disabled="true"])),
#vg-right .vg-k-btn.vg-k-hud-rail:active:where(:not(:disabled):not([aria-disabled="true"])),
#vg-avatar.vg-k-hud-portrait:active:where(:not(:disabled):not([aria-disabled="true"])),
#vg-next.vg-k-hud-cta:active:where(:not(:disabled):not([aria-disabled="true"])),
#vg-collect.vg-k-hud-cta:active:where(:not(:disabled):not([aria-disabled="true"])),
#vg-forecast.vg-k-btn:active:where(:not(:disabled):not([aria-disabled="true"])),
#vg-panel-body .vg-town-tab:active:where(:not(:disabled):not([aria-disabled="true"])) {
  transform: translateY(var(--vg-skin-lip));
  box-shadow: var(--vg-skin-pressed-shadow);
}
/* This chip owns translateX(-50%) in dialog-style.ts; never discard that anchor. */
.vg-k-btn.vg-nav-return:active:where(:not(:disabled):not([aria-disabled="true"])) {
  transform: translate(-50%,var(--vg-skin-lip));
}
/* Legacy back actions already force these paint properties with !important.
   Keep their sticky positioning, full width and zero border width. */
.vg-dialog-content :is(#vg-work-back,#vg-producer-back).vg-k-quiet,
#vg-panel-body.vg-dialog-content > :is(#vg-work-back,#vg-producer-back).vg-k-quiet:first-child {
  background: var(--vg-skin-lilac) !important;
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 var(--vg-skin-lip) 0 var(--vg-skin-lilac-lip) !important;
  color: var(--vg-skin-lilac-ink);
  text-decoration: none;
}
.vg-dialog-content :is(#vg-work-back,#vg-producer-back).vg-k-quiet { border-radius: 999px; }
#vg-panel-body.vg-dialog-content > :is(#vg-work-back,#vg-producer-back).vg-k-quiet:first-child { border-radius: 999px !important; }
.vg-dialog-content :is(#vg-work-back,#vg-producer-back).vg-k-quiet:active:where(:not(:disabled):not([aria-disabled="true"])),
#vg-panel-body.vg-dialog-content > :is(#vg-work-back,#vg-producer-back).vg-k-quiet:first-child:active:where(:not(:disabled):not([aria-disabled="true"])) {
  box-shadow: var(--vg-skin-pressed-shadow) !important;
}

/* Disabled controls remain readable. Native disabled/aria-disabled behavior is untouched. */
.vg-k-btn.vg-k-btn:is(:disabled,[aria-disabled="true"]),
#vg-panel-body .vg-town-tab:is(:disabled,[aria-disabled="true"]),
#vg-dock .vg-k-btn.vg-k-hud-dock:is(:disabled,[aria-disabled="true"]) {
  --vg-skin-fill: var(--vg-skin-muted);
  --vg-skin-edge: var(--vg-skin-muted-lip);
  --vg-skin-label: var(--vg-skin-muted-ink);
  background: var(--vg-skin-fill);
  border-color: var(--vg-skin-fill);
  color: var(--vg-skin-label);
  opacity: 1;
  transform: none;
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 2px 0 var(--vg-skin-edge);
  cursor: default;
}

/* Cream paper replaces the nested brown frames. Reading rows have no button lip. */
.vg-k-card.vg-dialog-card, .vg-dialog-content .vg-dialog-card {
  background: var(--vg-skin-paper);
  border-color: var(--vg-skin-rim);
  border-radius: var(--vg-r-card);
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight);
}
.vg-k-card .vg-k-card, .vg-dialog-card .vg-dialog-card { border-color: transparent; box-shadow: none; }
.vg-k-row-item {
  color: var(--vg-skin-ink);
  border-color: var(--vg-skin-rim);
  border-radius: var(--vg-r-card);
  background: var(--vg-skin-paper);
}
button.vg-k-row-item {
  background: var(--vg-skin-sky);
  border-color: var(--vg-skin-sky);
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 var(--vg-skin-lip) 0 var(--vg-skin-sky-lip);
}
.vg-k-row-item .vg-k-row-title,
.vg-k-title.vg-dialog-heading, .vg-dialog-content .vg-dialog-heading,
.vg-dialog-header > .vg-k-title {
  font-family: var(--vg-skin-font-display-family);
  font-weight: var(--vg-skin-font-display-weight);
  font-synthesis: none;
}
.vg-k-row-item .vg-k-row-detail { color: var(--vg-skin-ink-soft); opacity: 1; }
.vg-k-row-item .vg-k-row-meta {
  padding: var(--vg-gap-xs,4px) var(--vg-gap-sm,8px);
  background: var(--vg-skin-mint);
  color: var(--vg-skin-green-ink);
  border-radius: 999px;
}
.vg-k-note.vg-dialog-note { color: var(--vg-skin-ink-soft); line-height: 1.5; }
.vg-k-status { color: var(--vg-skin-ink); line-height: 1.5; }

details.vg-k-fold > summary {
  font-family: var(--vg-skin-font-display-family);
  font-weight: var(--vg-skin-font-display-weight);
  border-color: var(--vg-skin-sky);
  border-radius: var(--vg-r-card);
  background: var(--vg-skin-sky);
  color: var(--vg-skin-sky-ink);
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 var(--vg-skin-lip) 0 var(--vg-skin-sky-lip);
}
details.vg-k-fold > summary:active, button.vg-k-row-item:active:not(:disabled):not([aria-disabled="true"]) {
  transform: translateY(var(--vg-skin-lip));
  box-shadow: var(--vg-skin-pressed-shadow);
}
.vg-k-tabs > .vg-k-btn[aria-selected="true"],
.vg-k-btn.vg-k-chip[aria-pressed="true"],
.vg-k-btn[aria-pressed="true"]:not(.vg-k-primary):where(:not(.vg-k-hud)),
#vg-panel-body .vg-town-tab[aria-pressed="true"] {
  background: var(--vg-skin-fill);
  border-color: var(--vg-skin-fill);
  color: var(--vg-skin-label);
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 var(--vg-skin-lip) 0 var(--vg-skin-edge);
}
.vg-k-tabs > .vg-k-btn[aria-selected="true"]:active:where(:not(:disabled):not([aria-disabled="true"])),
.vg-k-btn.vg-k-chip[aria-pressed="true"]:active:where(:not(:disabled):not([aria-disabled="true"])),
.vg-k-btn[aria-pressed="true"]:not(.vg-k-primary):where(:not(.vg-k-hud):not(:disabled):not([aria-disabled="true"])):active,
#vg-panel-body .vg-town-tab[aria-pressed="true"]:active:where(:not(:disabled):not([aria-disabled="true"])) { box-shadow: var(--vg-skin-pressed-shadow); }
#vg-panel-body .vg-town-tabs {
  background: var(--vg-skin-cream);
  box-shadow: 0 -12px 0 var(--vg-skin-cream), 0 6px 6px -6px var(--vg-skin-shadow);
}
.vg-k-field :is(input:not([type=checkbox]):not([type=radio]),select,textarea) {
  border-color: var(--vg-skin-switch-off);
  border-radius: var(--vg-r-card);
  background: var(--vg-skin-paper);
  color: var(--vg-skin-ink);
  font-family: var(--vg-skin-font-body-family);
  box-shadow: inset 0 2px 3px var(--vg-skin-shadow);
}
.vg-k-field :is(input,textarea)::placeholder { color: var(--vg-skin-ink-soft); opacity: 1; }
.vg-k-field :is(input,select,textarea):disabled { color: var(--vg-skin-muted-ink); background: var(--vg-skin-muted); opacity: 1; }

/* A real native checkbox remains the control. Its label is the 48 px target. */
.vg-k-toggle {
  padding: var(--vg-skin-space-sm) var(--vg-skin-space-0);
  gap: var(--vg-skin-space-md);
  color: var(--vg-skin-ink);
  font-size: var(--vg-skin-font-body);
  font-weight: var(--vg-skin-font-strong-weight);
  line-height: var(--vg-skin-font-body-line);
  touch-action: manipulation;
}
.vg-k-toggle > input[type=checkbox] {
  appearance: none;
  -webkit-appearance: none;
  position: relative;
  box-sizing: border-box;
  width: 48px;
  height: 28px;
  padding: var(--vg-skin-space-0);
  border: 0;
  border-radius: 999px;
  background: transparent;
  box-shadow: none;
  cursor: inherit;
  overflow: visible;
}
.vg-k-toggle > input[type=checkbox]::before {
  content: '';
  position: absolute;
  inset: 0;
  box-sizing: border-box;
  border: 2px solid transparent;
  border-radius: 999px;
  background: var(--vg-skin-switch-off);
}
.vg-k-toggle > input[type=checkbox]::after {
  content: '';
  position: absolute;
  top: var(--vg-skin-space-xs);
  left: var(--vg-skin-space-xs);
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--vg-skin-paper);
  transition: transform 80ms ease-out;
}
.vg-k-toggle > input[type=checkbox]:checked::before { background: var(--vg-skin-switch-on); }
.vg-k-toggle > input[type=checkbox]:checked::after { transform: translateX(20px); }
.vg-k-toggle:has(> input:disabled) { color: var(--vg-skin-muted-ink); cursor: default; }
.vg-k-toggle > input[type=checkbox]:disabled::before {
  background: var(--vg-skin-muted);
  border-color: var(--vg-skin-muted-ink);
  border-style: dashed;
}
.vg-k-toggle > input[type=checkbox]:disabled::after { background: var(--vg-skin-muted-lip); }
.vg-k-toggle > input[type=checkbox]:focus-visible { outline: none; }
.vg-k-toggle > input[type=checkbox]:focus-visible::before {
  outline: 3px solid var(--vg-skin-focus);
  outline-offset: 3px;
}

/* Sheet and native dialog geometry still belongs to its original owner. */
#vg-panel > .vg-card, dialog.vg-dialog-shell {
  background: var(--vg-skin-cream);
  border-color: var(--vg-skin-rim);
  border-radius: var(--vg-r-panel);
  box-shadow: var(--vg-raised);
}
dialog.vg-dialog-shell::backdrop { background: var(--vg-skin-backdrop); }
#vg-panel-title, .vg-dialog-header > .vg-k-title {
  padding: var(--vg-gap-sm,8px) var(--vg-gap-md,12px);
  background: var(--vg-skin-mint);
  color: var(--vg-skin-green-ink);
  border-bottom-color: transparent;
  border-radius: 18px 18px 18px 6px;
  font-family: var(--vg-skin-font-display-family);
}
#vg-panel-head::after { background: linear-gradient(var(--vg-skin-cream),transparent); }
.vg-valley-chapter {
  background: var(--vg-skin-mint);
  color: var(--vg-skin-green-ink);
  border-color: var(--vg-skin-mint-lip);
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight);
}
.vg-valley-chapter .vg-chapter-kicker { color: var(--vg-skin-green-ink); }
#vg-panel-head .vg-k-btn.vg-k-icon, .vg-dialog-header .vg-k-btn.vg-k-icon {
  border-radius: 50%;
  background: var(--vg-skin-peach);
  border-color: var(--vg-skin-peach);
  color: var(--vg-skin-ink);
}
.vg-dialog-content button.vg-recipe-card,
.vg-dialog-content button.vg-recipe-card.vg-work-main {
  border-color: var(--vg-skin-peach);
  border-radius: var(--vg-r-card);
  background: var(--vg-skin-paper);
  color: var(--vg-skin-ink);
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 var(--vg-skin-lip) 0 var(--vg-skin-peach-lip);
  font-family: var(--vg-skin-font-body-family);
  transition: transform 80ms ease-out;
}
.vg-recipe-art { background: var(--vg-skin-butter); color: var(--vg-skin-butter-ink); border-radius: 14px; }
.vg-recipe-name strong { font-family: var(--vg-skin-font-display-family); font-weight: var(--vg-skin-font-display-weight); }
.vg-recipe-plan, .vg-recipe-card[data-recipe-ready="true"] .vg-recipe-plan {
  padding: var(--vg-gap-xs,4px) var(--vg-gap-sm,8px);
  background: var(--vg-skin-mint);
  color: var(--vg-skin-green-ink);
  border-radius: 999px;
}
.vg-recipe-time { border-color: var(--vg-skin-rim); color: var(--vg-skin-ink-soft); }
.vg-dialog-content button.vg-recipe-card:active:not(:disabled):not([aria-disabled="true"]) {
  transform: translateY(var(--vg-skin-lip));
  box-shadow: var(--vg-skin-pressed-shadow);
}
@media (hover:hover) and (pointer:fine) {
  .vg-dialog-content button.vg-recipe-card:hover:not(:disabled):not(.vg-dialog-primary):not(.vg-work-main):not(.vg-k-row-item) {
    background: var(--vg-skin-cream);
    border-color: var(--vg-skin-peach);
  }
}
.vg-dialog-content button.vg-recipe-card:disabled {
  color: var(--vg-skin-muted-ink);
  background: var(--vg-skin-muted);
  border-color: var(--vg-skin-muted-lip);
  box-shadow: none;
  opacity: 1;
}
.vg-recipe-card:disabled .vg-recipe-art { background: var(--vg-skin-muted-lip); color: var(--vg-skin-ink); }

/* Preserve feedback indicators; only their paint changes. No extra pseudo-element
   on a button: HUD badges and the kit's busy/done glyph already own ::after. */
.vg-k-btn.vg-k-btn[data-state="done"], .vg-k-row-item[data-state="done"] {
  box-shadow: inset 0 0 0 3px var(--vg-skin-switch-on), 0 var(--vg-skin-lip) 0 var(--vg-skin-edge,var(--vg-skin-sky-lip));
}
.vg-k-btn.vg-k-btn[data-state="failed"], .vg-k-row-item[data-state="failed"] { border-color: var(--vg-skin-rose-ink); }
.vg-k-btn.vg-k-quiet[data-state="done"] { color: var(--vg-skin-green-ink); }
.vg-k-btn.vg-k-btn[data-state]:active:where(:not(:disabled):not([aria-disabled="true"])) { box-shadow: var(--vg-skin-pressed-shadow); }

/* Inset rings survive the sheet body's clipping. Never hide the keyboard ring
   to make a control look pressed, selected, quiet or disabled by ARIA. */
.vg-k-btn.vg-k-btn:focus-visible, button.vg-k-row-item:focus-visible,
details.vg-k-fold > summary:focus-visible,
.vg-k-field :is(input,select,textarea):focus-visible,
#vg-panel-head .vg-nav-back:focus-visible,
#vg-dock .vg-k-btn.vg-k-hud-dock:focus-visible,
#vg-right .vg-k-btn.vg-k-hud-rail:focus-visible,
#vg-panel-body .vg-town-tab:focus-visible {
  outline: 3px solid var(--vg-skin-focus);
  outline-offset: -3px;
}

/* Reduced motion keeps the depth cue but removes the sink and refusal shake.
   A checked switch still changes position instantly to communicate its state. */
[data-motion=reduce] .vg-k-btn.vg-k-btn,
[data-motion=reduce] button.vg-k-row-item,
[data-motion=reduce] details.vg-k-fold > summary,
[data-motion=reduce] .vg-k-toggle > input { transition: none; animation: none; }
[data-motion=reduce] .vg-k-toggle > input::after { transition: none; }
[data-motion=reduce] .vg-k-btn.vg-k-btn:active,
[data-motion=reduce] #vg-dock .vg-k-btn.vg-k-hud-dock:active,
[data-motion=reduce] #vg-right .vg-k-btn.vg-k-hud-rail:active,
[data-motion=reduce] #vg-avatar.vg-k-hud-portrait:active,
[data-motion=reduce] #vg-next.vg-k-hud-cta:active,
[data-motion=reduce] #vg-collect.vg-k-hud-cta:active,
[data-motion=reduce] #vg-forecast.vg-k-btn:active,
[data-motion=reduce] #vg-panel-body .vg-town-tab:active,
[data-motion=reduce] button.vg-k-row-item:active:not(:disabled):not([aria-disabled="true"]),
[data-motion=reduce] .vg-dialog-content button.vg-recipe-card:active:not(:disabled):not([aria-disabled="true"]),
[data-motion=reduce] details.vg-k-fold > summary:active { transform: none; }
[data-motion=reduce] .vg-k-btn.vg-nav-return:active { transform: translateX(-50%); }
[data-motion=reduce] :is(.vg-k-btn,.vg-k-row-item)[data-state="busy"]::after,
[data-motion=reduce] button[aria-busy="true"]::after { animation: none; }
@media (prefers-reduced-motion:reduce) {
  .vg-k-btn.vg-k-btn, button.vg-k-row-item, details.vg-k-fold > summary,
  .vg-k-toggle > input::after { transition: none; animation: none; }
  .vg-k-btn.vg-k-btn:active,
  #vg-dock .vg-k-btn.vg-k-hud-dock:active,
  #vg-right .vg-k-btn.vg-k-hud-rail:active,
  #vg-avatar.vg-k-hud-portrait:active,
  #vg-next.vg-k-hud-cta:active,
  #vg-collect.vg-k-hud-cta:active,
  #vg-forecast.vg-k-btn:active,
  #vg-panel-body .vg-town-tab:active,
  button.vg-k-row-item:active:not(:disabled):not([aria-disabled="true"]),
  .vg-dialog-content button.vg-recipe-card:active:not(:disabled):not([aria-disabled="true"]),
  details.vg-k-fold > summary:active { transform: none; }
  .vg-k-btn.vg-nav-return:active { transform: translateX(-50%); }
  :is(.vg-k-btn,.vg-k-row-item)[data-state="busy"]::after,
  button[aria-busy="true"]::after { animation: none; }
}
@media (forced-colors:active) {
  /* Return the actual native checkbox, rather than relying on painted colors. */
  .vg-k-toggle > input[type=checkbox] { appearance: auto; -webkit-appearance: auto; }
  .vg-k-toggle > input[type=checkbox]::before,
  .vg-k-toggle > input[type=checkbox]::after { content: none; }
  .vg-k-toggle > input[type=checkbox]:focus-visible { outline: 3px solid Highlight; outline-offset: 3px; }
  .vg-k-btn.vg-k-btn, .vg-k-field :is(input,select,textarea),
  details.vg-k-fold > summary, .vg-k-row-item { border-color: ButtonText; }
}

/* v2 · one spacing and type vocabulary, including the phone's compact chrome. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body, #app {
  font-size: var(--vg-skin-font-body);
  font-weight: var(--vg-skin-font-body-weight);
  line-height: var(--vg-skin-font-body-line);
  letter-spacing: var(--vg-skin-font-body-tracking);
}
.vg-dialog-content.vg-dialog-content, #vg-panel-body.vg-dialog-content {
  font-size: var(--vg-skin-font-body) !important;
  font-weight: var(--vg-skin-font-body-weight);
  line-height: var(--vg-skin-font-body-line);
}
.vg-k-btn.vg-k-btn:where(:not(.vg-k-hud)) {
  padding: var(--vg-skin-space-md) var(--vg-skin-space-lg);
  font-size: var(--vg-skin-font-label) !important;
  line-height: var(--vg-skin-font-label-line);
  letter-spacing: var(--vg-skin-font-display-tracking);
  gap: var(--vg-skin-space-xs);
  max-width: 100%;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
.vg-k-btn > .vg-k-label { gap: var(--vg-skin-space-sm); max-width: 100%; overflow-wrap: normal; word-break: normal; }
.vg-k-btn > .vg-k-sub, .vg-k-btn.vg-k-hud-cta > .vg-k-sub, .vg-k-btn.vg-k-tile > .vg-k-sub {
  font-size: var(--vg-skin-font-small);
  font-weight: var(--vg-skin-font-small-weight);
  line-height: var(--vg-skin-font-small-line);
  letter-spacing: var(--vg-skin-font-body-tracking);
}
.vg-k-btn.vg-k-quiet, .vg-k-btn.vg-k-chip {
  padding: var(--vg-skin-space-sm) var(--vg-skin-space-md);
}
.vg-k-btn.vg-k-chip {
  font-size: var(--vg-skin-font-small) !important;
  white-space: nowrap;
}
.vg-k-btn.vg-k-chip > .vg-k-label { white-space: nowrap; overflow-wrap: normal; }
.vg-k-btn.vg-k-icon, .vg-k-btn.vg-k-fab {
  padding: var(--vg-skin-space-0);
  font-size: var(--vg-skin-font-icon) !important;
}
.vg-k-btn.vg-k-tile {
  padding: var(--vg-skin-space-sm);
  font-size: var(--vg-skin-font-small) !important;
  gap: var(--vg-skin-space-xs);
}
.vg-k-btn.vg-k-tile > .vg-k-label { gap: var(--vg-skin-space-xs); }

.vg-k-card.vg-dialog-card, .vg-dialog-content .vg-dialog-card {
  padding: var(--vg-skin-space-lg);
}
.vg-k-row-item {
  padding: var(--vg-skin-space-md) var(--vg-skin-space-lg);
  gap: var(--vg-skin-space-sm);
}
/* Reserve the existing absolute busy/done indicator's end slot from the start.
   Centered action buttons reserve it symmetrically (32 px on both sides).
   Left-aligned whole-row buttons reserve only their trailing slot. */
button.vg-k-row-item { padding-inline-end: var(--vg-skin-space-2xl); }
.vg-k-row-text { overflow-wrap: break-word; }
.vg-k-row-item .vg-k-row-title {
  font-size: var(--vg-skin-font-heading);
  line-height: var(--vg-skin-font-heading-line);
  letter-spacing: var(--vg-skin-font-display-tracking);
}
.vg-k-row-item .vg-k-row-detail,
.vg-k-row-item .vg-k-row-meta,
.vg-k-note.vg-dialog-note, .vg-dialog-content .vg-dialog-note,
.vg-k-field > label, .vg-recipe-inputs, .vg-recipe-time {
  font-size: var(--vg-skin-font-small);
  font-weight: var(--vg-skin-font-small-weight);
  line-height: var(--vg-skin-font-small-line);
}
.vg-k-row-item .vg-k-row-meta, .vg-stat b, .vg-stat-max {
  font-family: var(--vg-skin-font-display-family);
  font-weight: var(--vg-skin-font-display-weight);
  font-variant-numeric: tabular-nums;
}
.vg-k-row-item .vg-k-row-meta { padding: var(--vg-skin-space-xs) var(--vg-skin-space-sm); }
.vg-k-title.vg-dialog-heading, .vg-dialog-content .vg-dialog-heading {
  font-size: var(--vg-skin-font-heading);
  line-height: var(--vg-skin-font-heading-line);
  letter-spacing: var(--vg-skin-font-display-tracking);
}
details.vg-k-fold > summary {
  padding: var(--vg-skin-space-md) var(--vg-skin-space-lg);
  font-size: var(--vg-skin-font-label);
  line-height: var(--vg-skin-font-label-line);
  gap: var(--vg-skin-space-sm);
  touch-action: manipulation;
}
details.vg-k-fold > .vg-k-fold-body { padding: var(--vg-skin-space-md) var(--vg-skin-space-0) var(--vg-skin-space-0); }
.vg-k-field { gap: var(--vg-skin-space-xs); }
.vg-k-actions, .vg-k-list, .vg-k-tabs, .vg-k-section, details.vg-k-fold {
  padding: var(--vg-skin-space-0);
}
.vg-k-field :is(input:not([type=checkbox]):not([type=radio]),select,textarea) {
  padding: var(--vg-skin-space-md) var(--vg-skin-space-lg);
  font-size: max(16px,var(--vg-skin-font-body));
  font-weight: var(--vg-skin-font-body-weight);
  line-height: var(--vg-skin-font-body-line);
}
/* Keep native selection and keyboard behavior, with one cross-platform closed
   field surface. WebKit's menulist appearance discards author padding/radius. */
.vg-k-field select { height: auto; }
.vg-k-field[data-ui="field"] > select:not([multiple]):where(:not([size]),[size="1"]) {
  appearance: none;
  -webkit-appearance: none;
  height: max(48px,calc(1em * var(--vg-skin-font-body-line) + 2 * var(--vg-skin-space-md) + 4px));
  padding-inline-end: var(--vg-skin-space-2xl);
  grid-column: 1;
  grid-row: 2;
}
.vg-k-field[data-ui="field"]:has(> select:not([multiple]):where(:not([size]),[size="1"]))::after {
  content: '';
  grid-column: 1;
  grid-row: 2;
  align-self: center;
  justify-self: end;
  width: var(--vg-skin-space-sm);
  height: var(--vg-skin-space-sm);
  margin-inline-end: var(--vg-skin-space-lg);
  border-right: 2px solid var(--vg-skin-ink-soft);
  border-bottom: 2px solid var(--vg-skin-ink-soft);
  transform: rotate(45deg);
  pointer-events: none;
}
.vg-k-field[data-ui="field"]:has(> select:disabled)::after { border-color: var(--vg-skin-muted-ink); }
.vg-k-status { font-size: var(--vg-skin-font-body); font-weight: var(--vg-skin-font-strong-weight); }
/* showLine() emits a bare text node followed by quiet buttons. The anonymous
   text flex item stays first. A zero-height, full-line pseudo-item separates
   it from the ordered actions; no text wrapping or kit markup change needed. */
.vg-k-status:has(> .vg-k-quiet) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vg-skin-space-sm);
}
.vg-k-status:has(> .vg-k-quiet)::before { content: ''; order: 1; flex-basis: 100%; }
.vg-k-status > .vg-k-quiet { order: 2; }
/* action-feedback.css also owns aria-busy ::after and otherwise offsets the
   kit spinner twice. Use its exact hook to center that one shared indicator. */
:is(button.vg-k-btn,button.vg-k-row-item)[aria-busy="true"]:not(#vg-splash-play)::after {
  top: 50%;
  right: var(--vg-skin-space-2xs);
  width: 14px;
  height: 14px;
  margin-top: -7px;
  background: transparent;
}

/* Explicitly authorized local reflow: keep each priority name intact. */
#vg-panel-body .vg-town-tabs {
  flex-wrap: wrap;
  padding-block: var(--vg-skin-space-sm);
}
#vg-panel-body .vg-town-tabs > .vg-town-tab {
  flex: 0 1 auto;
  padding: var(--vg-skin-space-sm) var(--vg-skin-space-md);
  font-size: var(--vg-skin-font-small) !important;
  line-height: var(--vg-skin-font-label-line);
  white-space: nowrap;
  overflow-wrap: normal;
  text-wrap: nowrap;
}
#vg-panel-body:has(.vg-town-tabs) { scroll-padding-top: calc(2 * var(--vg-k-h) + var(--vg-skin-space-xl)); }

/* Original shell dimensions, scrolling, safe-area anchors and layout stay owned
   by the game. Only its inner padding and type are normalized. */
#vg-panel#vg-panel > .vg-card { padding: var(--vg-skin-space-lg) !important; }
#vg-panel-head { padding-bottom: var(--vg-skin-space-sm); gap: var(--vg-skin-space-sm); }
#vg-panel#vg-panel #vg-panel-title {
  padding: var(--vg-skin-space-sm) var(--vg-skin-space-md);
  font-size: var(--vg-skin-font-title) !important;
  line-height: var(--vg-skin-font-title-line);
  letter-spacing: var(--vg-skin-font-display-tracking);
  margin-bottom: var(--vg-skin-space-0) !important;
}
#vg-panel#vg-panel #vg-panel-body {
  padding: var(--vg-skin-space-md) var(--vg-skin-space-0) var(--vg-skin-space-lg);
}
dialog.vg-dialog-shell { padding: var(--vg-skin-space-lg); }
.vg-dialog-header { gap: var(--vg-skin-space-sm); }
.vg-dialog-header > .vg-k-title {
  padding: var(--vg-skin-space-sm) var(--vg-skin-space-md);
  font-size: var(--vg-skin-font-title);
  line-height: var(--vg-skin-font-title-line);
}
.vg-k-dialog-body { padding: var(--vg-skin-space-md) var(--vg-skin-space-0); }
dialog.vg-dialog-shell > .vg-dialog-header::before {
  inset: calc(-1 * var(--vg-skin-space-lg)) calc(-1 * var(--vg-skin-space-lg)) 0;
}
.vg-dialog-content button.vg-recipe-card,
.vg-dialog-content button.vg-recipe-card.vg-work-main { padding: var(--vg-skin-space-lg); }
.vg-recipe-head { gap: var(--vg-skin-space-md); margin-bottom: var(--vg-skin-space-md); }
.vg-recipe-name { gap: var(--vg-skin-space-xs); }
.vg-recipe-name strong { font-size: var(--vg-skin-font-heading); line-height: var(--vg-skin-font-heading-line); }
.vg-recipe-plan { font-size: var(--vg-skin-font-small); line-height: var(--vg-skin-font-small-line); }
.vg-recipe-yield { font-size: var(--vg-skin-font-body); font-weight: var(--vg-skin-font-strong-weight); line-height: var(--vg-skin-font-body-line); }
.vg-recipe-time { padding-top: var(--vg-skin-space-sm); }
.vg-recipe-card[data-recipe-ready="false"] .vg-recipe-inputs { color: var(--vg-skin-rose-ink); }

/* HUD sizes are deliberately compact; their text remains in rem for Text size. */
.vg-k-btn.vg-k-hud.vg-k-hud-dock {
  padding: var(--vg-skin-space-xs) var(--vg-skin-space-2xs) !important;
  font-size: var(--vg-skin-font-dock) !important;
  line-height: var(--vg-skin-font-label-line);
}
.vg-k-btn.vg-k-hud.vg-k-hud-rail {
  padding: var(--vg-skin-space-xs) var(--vg-skin-space-0) !important;
  font-size: var(--vg-skin-font-label) !important;
}
.vg-k-btn.vg-k-hud.vg-k-hud-pill {
  padding: var(--vg-skin-space-sm) var(--vg-skin-space-md) !important;
  font-size: var(--vg-skin-font-heading) !important;
}
.vg-k-btn.vg-k-hud:is(.vg-k-hud-chip,.vg-k-hud-cta) {
  padding: var(--vg-skin-space-sm) var(--vg-skin-space-md) !important;
  font-size: var(--vg-skin-font-small) !important;
  line-height: var(--vg-skin-font-label-line);
}
.vg-k-btn.vg-k-hud.vg-k-hud-fold {
  padding: var(--vg-skin-space-xs) var(--vg-skin-space-sm) !important;
  font-size: var(--vg-skin-font-small) !important;
}
.vg-k-btn.vg-k-hud:is(.vg-k-hud-portrait,.vg-k-hud-plus) {
  padding: var(--vg-skin-space-0) !important;
  font-size: var(--vg-skin-font-icon) !important;
}
.vg-k-btn.vg-k-hud-rail small, .vg-k-btn.vg-k-hud-dock .vg-dock-label {
  font-size: var(--vg-skin-font-dock);
  line-height: var(--vg-skin-font-label-line);
}
.vg-k-btn.vg-k-hud-dock .vg-dock-ico { width: 24px; height: 24px; font-size: 24px; }
#vg-dock .vg-k-hud-dock { gap: var(--vg-skin-space-xs); }
.vg-dock { padding: var(--vg-skin-space-xs); }
#vg-modes, #vg-meta { gap: var(--vg-skin-space-xs); }
body.vg-street-mode .vg-k-btn.vg-k-hud:is(.vg-k-hud-chip,.vg-k-hud-cta) {
  padding: var(--vg-skin-space-xs) var(--vg-skin-space-md) !important;
  font-size: var(--vg-skin-font-small) !important;
}

/* Two static shadows maximum, no shadow transitions or per-row GPU promotion. */
.vg-card[role="button"] { transition: transform 80ms ease-out; }
#vg-avatar.vg-k-hud-portrait, .vg-k-btn.vg-k-hud-pill { filter: none; }
#vg-next.vg-k-hud-cta, #vg-hall.vg-hall-ready { animation: none; }
body.vg-threat-present #vg-panel-body .vg-work-main {
  box-shadow: 0 var(--vg-skin-lip) 0 var(--vg-skin-green-lip), 0 0 0 var(--vg-skin-space-xs) var(--vg-skin-cream);
}
body.vg-threat-present #vg-panel-body .vg-work-main:active:not(:disabled):not([aria-disabled="true"]) {
  box-shadow: 0 0 0 var(--vg-skin-space-xs) var(--vg-skin-cream);
}
@media (max-width:960px) {
  .vg-k-btn.vg-k-hud.vg-k-hud-pill {
    padding: var(--vg-skin-space-0) !important;
    font-size: var(--vg-skin-font-counter) !important;
  }
  .vg-k-hud-pill > .vg-k-label { gap: var(--vg-skin-space-xs); }
  body #vg-tr#vg-tr #vg-coins[data-wide] { font-size: var(--vg-skin-font-counter-wide) !important; }
  body #vg-tr#vg-tr .vg-stat-max { font-size: var(--vg-skin-font-dock); }
  body #vg-topleft#vg-topleft > .vg-card { padding: var(--vg-skin-space-0) var(--vg-skin-space-sm) var(--vg-skin-space-0) var(--vg-skin-space-0) !important; }
  body #vg-topleft#vg-topleft .vg-tl-meta { font-size: var(--vg-skin-font-dock) !important; }
  body #vg-topleft#vg-topleft #vg-season { font-size: var(--vg-skin-font-dock); }
}
@media (orientation:landscape) and (max-height:500px) {
  body #vg-dock#vg-dock { padding: var(--vg-skin-space-2xs) var(--vg-skin-space-xs) !important; }
  .vg-k-btn.vg-k-hud.vg-k-hud-dock { padding: var(--vg-skin-space-2xs) !important; }
  #vg-dock .vg-k-hud-dock .vg-dock-ico { width: 20px; height: 20px; font-size: 20px; }
  #vg-panel-body .vg-town-tabs { position: static; box-shadow: none; }
  #vg-panel-body:has(.vg-town-tabs) { scroll-padding-top: var(--vg-skin-space-0); }
  #vg-panel#vg-panel #vg-panel-body { padding-bottom: calc(var(--vg-skin-space-lg) + env(safe-area-inset-bottom,0px)); }
}
/* The game stamps data-motion; the OS rule also works before preferences mount. */
@media (prefers-reduced-motion:reduce) {
  #vg-panel > .vg-card > :is(#vg-panel-head,#vg-panel-body),
  dialog.vg-dialog-shell.vg-dialog-entering > * { animation: none; }
}
@media (hover:hover) and (pointer:fine) {
  .vg-k-btn.vg-k-btn[aria-disabled="true"]:hover:not(.vg-k-primary):not(.vg-k-danger):not(.vg-k-quiet):where(:not(.vg-k-hud)) {
    background: var(--vg-skin-muted);
  }
}

/* v3 desktop · match the game's desktop and short-landscape boundaries.
   These rules do not run in the 390 px or 844 × 390 phone layouts. */
@media (min-width:961px) and (min-height:501px) {
  :root {
    --vg-skin-font-title: 1.5rem;
    --vg-skin-font-heading: 1.25rem;
    /* v3.2: label/body/small keep their phone sizes (16/16/14) on desktop so each kit kind draws one box on every
       viewport (test:buttons, owner 30 Oct "one box per kind"); titles, headings and dock captions still step up. */
    --vg-skin-font-dock: .875rem;
  }

  /* Maxima bound the controller's chosen width, not its position or tray mode. */
  #vg-panel {
    max-width: min(480px,calc(100vw - var(--vg-chrome-x) - var(--vg-chrome-r)));
  }
  dialog.vg-dialog-shell {
    max-width: min(480px,calc(100vw - var(--vg-chrome-x) - var(--vg-chrome-r)));
  }
  .vg-k-btn.vg-k-wide, .vg-k-field,
  .vg-k-actions:not(.vg-k-row) > .vg-k-btn:where(:not(.vg-k-hud):not(.vg-k-chip):not(.vg-k-icon)) {
    max-width: 440px;
  }

  .vg-valley-chapter strong { font-size: var(--vg-skin-font-title); }
  .vg-valley-chapter :is(.vg-chapter-kicker,.vg-chapter-detail) {
    font-size: var(--vg-skin-font-small);
    line-height: var(--vg-skin-font-small-line);
  }

  /* Same padded boxes at rest, on hover, and when keyboard focus arrives. */
  #vg-dock { gap: var(--vg-skin-space-sm); }
  #vg-dock :is(#vg-modes,#vg-meta) { gap: var(--vg-skin-space-sm); }
  .vg-k-btn.vg-k-hud.vg-k-hud-dock {
    padding: var(--vg-skin-space-sm) !important;
  }
  #vg-dock .vg-k-hud-dock { gap: var(--vg-skin-space-sm); }
  #vg-dock .vg-key {
    top: var(--vg-skin-space-2xs);
    right: var(--vg-skin-space-2xs);
    padding: var(--vg-skin-space-0) var(--vg-skin-space-2xs);
    font-size: var(--vg-skin-font-counter);
    line-height: var(--vg-skin-font-label-line);
  }
  #vg-right .vg-k-btn.vg-k-hud-rail {
    width: 72px;
    min-height: 64px !important;
  }
  #vg-right .vg-k-hud-rail small { max-width: 100%; overflow-wrap: normal; }
  .vg-k-btn.vg-k-hud.vg-k-hud-pill {
    min-height: 56px !important;
    padding: var(--vg-skin-space-sm) var(--vg-skin-space-lg) !important;
    line-height: var(--vg-skin-font-label-line);
  }
  #vg-avatar.vg-k-hud-portrait { font-size: 2rem !important; }
  #vg-topleft > .vg-card {
    padding: var(--vg-skin-space-md) !important;
    gap: var(--vg-skin-space-md) !important;
  }
  #vg-topleft :is(.vg-tl-meta,#vg-season) {
    font-size: var(--vg-skin-font-small);
    line-height: var(--vg-skin-font-small-line);
  }

  /* The activity summary's old :focus rule suppresses its own ring and rings
     the card instead. Keep that cue and give the actual control its ring too. */
  #vg-activity.vg-dialog-content #vg-activity-summary:focus-visible,
  .vg-dialog-content button.vg-recipe-card:focus-visible,
  dialog.vg-k-dialog:focus-visible {
    outline: 3px solid var(--vg-skin-focus);
    outline-offset: -3px;
  }
  .vg-k-field select { cursor: pointer; }
  .vg-k-field :is(input,textarea) { cursor: text; }
  .vg-k-field :is(input,select,textarea):disabled,
  button.vg-k-row-item:is(:disabled,[aria-disabled="true"]) { cursor: default; }
  [data-motion=reduce] .vg-dialog-content button.vg-recipe-card { transition: none; animation: none; }

  /* Shared paint value for real hover and the tile's frozen example. */
  .vg-k-btn { --vg-skin-hover-fill: color-mix(in srgb,var(--vg-skin-fill),var(--vg-skin-paper) 18%); }
  #vg-dock .vg-k-hud-dock:not(.is-on) {
    --vg-skin-hover-fill: color-mix(in srgb,var(--vg-skin-mint),var(--vg-skin-cream) 55%);
  }
}

@media (min-width:961px) and (min-height:501px) and (hover:hover) and (pointer:fine) {
  .vg-k-btn.vg-k-btn:hover:not(:disabled):not(.vg-k-primary):not(.vg-k-danger):not(.vg-k-quiet):where(:not(.vg-k-hud):not([aria-disabled="true"])),
  .vg-k-btn.vg-k-btn:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-dock .vg-k-btn.vg-k-hud-dock:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-right .vg-k-btn.vg-k-hud-rail:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-avatar.vg-k-hud-portrait:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-next.vg-k-hud-cta:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-collect.vg-k-hud-cta:hover:where(:not(:disabled):not([aria-disabled="true"])),
  #vg-panel-body .vg-town-tab:hover:where(:not(:disabled):not([aria-disabled="true"])) {
    background: var(--vg-skin-hover-fill);
  }
  button.vg-k-row-item:hover:not(:disabled):not([aria-disabled="true"]),
  details.vg-k-fold > summary:hover {
    background: color-mix(in srgb,var(--vg-skin-sky),var(--vg-skin-paper) 18%);
  }
  .vg-dialog-content button.vg-recipe-card:hover:not(:disabled):not(.vg-dialog-primary):not(.vg-work-main):not(.vg-k-row-item) {
    background: var(--vg-skin-paper);
    border-color: var(--vg-skin-peach-lip);
  }
  .vg-k-btn.vg-k-btn[aria-disabled="true"]:hover:not(.vg-k-primary):not(.vg-k-danger):not(.vg-k-quiet):where(:not(.vg-k-hud)) {
    background: var(--vg-skin-muted);
  }
}

/* Only the pale recipe surface needs a lift to supplement its border cue.
   Other controls brighten without moving. A physical press always wins. */
@media (min-width:961px) and (min-height:501px) and (hover:hover) and (pointer:fine) and (prefers-reduced-motion:no-preference) {
  .vg-dialog-content button.vg-recipe-card:hover:not(:disabled):not(.vg-dialog-primary):not(.vg-work-main):not(.vg-k-row-item):where(:not(:active):not([aria-disabled="true"])) {
    transform: translateY(-1px);
  }
  [data-motion=reduce] .vg-dialog-content button.vg-recipe-card:hover:not(:disabled):not(.vg-dialog-primary):not(.vg-work-main):not(.vg-k-row-item):where(:not(:active):not([aria-disabled="true"])) {
    transform: none;
  }
}
@media (min-width:961px) and (min-height:501px) and (prefers-reduced-motion:reduce) {
  .vg-dialog-content button.vg-recipe-card { transition: none; animation: none; }
}

/* ---- v3.1 fixes, 3 Nov (owner's desktop screenshot at ~1000x600, Hall 30) ------------------------------------------ */
/* The wallet stays one row on desktop: five pills (Coins, Gems, Energy, Knowledge, Influence) plus the shop "+" did not
   fit at the v3 desktop pill size (20 px, 56 px tall) and wrapped into two rows with the "+" between them. Big numbers
   are also shortened by the HUD (13.8M, exact in the tooltip). */
@media (min-width:961px) and (min-height:501px) {
  .vg-k-btn.vg-k-hud.vg-k-hud-pill {
    min-height: 48px !important;
    padding: var(--vg-skin-space-xs) var(--vg-skin-space-md) !important;
    font-size: var(--vg-skin-font-label) !important;
  }
  body #vg-tr#vg-tr .vg-wallet-stats { flex-wrap: nowrap; }
}
@media (min-width:1280px) and (min-height:501px) { body #vg-tr#vg-tr .vg-wallet { max-width: none; } }
/* A narrow desktop window (961-1279 px): smaller pills keep one row between the town card and the right rail. */
@media (min-width:961px) and (max-width:1279px) and (min-height:501px) {
  .vg-k-btn.vg-k-hud.vg-k-hud-pill {
    padding: var(--vg-skin-space-2xs, 4px) var(--vg-skin-space-sm) !important;
    font-size: var(--vg-skin-font-small) !important;
  }
  body #vg-tr#vg-tr .vg-wallet, body #vg-tr#vg-tr .vg-wallet-stats { gap: var(--vg-skin-space-2xs, 4px); }
  body #vg-tr#vg-tr .vg-wallet { max-width: none; }
}
/* Town topic chips are kit chips marked data-town-tab (the v3 rule named a .vg-town-tab class the markup does not have):
   size to their words and wrap whole chips, so "Services & happiness" is never clipped. */
#vg-panel-body .vg-town-tabs { flex-wrap: wrap; }
#vg-panel-body .vg-town-tabs > [data-town-tab] {
  flex: 1 0 auto;
  white-space: nowrap;
  padding-inline: var(--vg-skin-space-md);
}
/* A wide action whose label wraps balances its lines, so a trailing "→" never sits alone on the last line. */
.vg-k-btn .vg-k-label { text-wrap-style: balance; } /* v3.2: the style longhand only; the text-wrap shorthand reset nowrap */
/* Phones: the three topics stay one row of equal chips; a long name takes two balanced lines rather than a lone
   full-width chip on a second row. */
@media (max-width:960px) {
  #vg-panel-body .vg-town-tabs { flex-wrap: nowrap; }
  #vg-panel-body .vg-town-tabs > [data-town-tab] {
    flex: 1 1 0; min-width: min-content;
    white-space: normal; text-wrap-style: balance;
  }
  #vg-panel-body .vg-town-tabs > [data-town-tab] :is(.vg-k-label, span) { white-space: normal !important; text-wrap-style: balance; overflow-wrap: normal; }
}

/* ---- v3.2 in-game fit, 3 Nov (owner: "the css needs to optimized"; measured by qa/kit-fit-probe.mjs, npm run
   test:kit-fit) -------------------------------------------------------------------------------------------------------
   Kit buttons keep 16 px ends (was 32): the busy/✓ indicator now sits inside that end (2 px in, 14 px wide), so the
   label never shares space with it and three buttons fit side by side on a 390 px phone. Words never split. */
:is(.vg-k-btn,.vg-k-row-item)[data-state]::after { right: var(--vg-skin-space-2xs); }
:is(.vg-k-btn,.vg-k-row-item)[data-state="busy"]::after { width: 14px; height: 14px; margin-top: -7px; }
.vg-k-btn > :is(.vg-k-label,.vg-k-sub), details.vg-k-fold > summary { overflow-wrap: normal; word-break: normal; hyphens: manual; }

/* Equal-share rows size each button to its words first (Talk card: Profile, Type, Goodbye), then share what is left;
   a row that cannot hold them wraps whole buttons instead of squeezing a word. */
.vg-chat-foot > .vg-k-btn { flex: 1 1 auto; min-width: min-content; }
.vg-chat-foot > .vg-k-btn > .vg-k-label { white-space: nowrap; }

/* Pickers: content-sized pills that wrap as whole pills (Talk topics, road surfaces). One label font per chip: the
   label in the display face, the price/sub-line in the reading face under it. */
#vg-chat-topics.vg-k-actions { margin: 0; }
#vg-chat-topics > .vg-k-btn.vg-k-chip { flex: 1 1 auto; padding: var(--vg-skin-space-sm) var(--vg-skin-space-md); }
#vg-road-picker { width: max-content; max-width: calc(100vw - 16px); flex-wrap: wrap; justify-content: center; }
#vg-road-picker > .vg-k-btn.vg-k-chip, #vg-road-picker > #vg-road-roundabout { flex: 1 1 auto; min-width: min-content; }
#vg-road-picker > .vg-k-btn.vg-k-chip > .vg-k-sub { white-space: nowrap; }

/* A two- or three-column action group with a single action gives it the whole row, so "Grow sugarcane →" and
   "Grow tomato →" draw the same width on every crop card instead of one wrapping in half a row. */
.vg-k-actions:is(.vg-k-cols2,.vg-k-cols3) > .vg-k-btn:only-child { grid-column: 1 / -1; }

/* Town topics: an opaque strip flush with the top of the sheet's scroll area (no band above it where a scrolled card
   shows), edge to edge, with a rim under it so a card passing beneath is cut by a line, not by the chips' lips. */
#vg-panel-body .vg-town-tabs {
  top: calc(-1 * var(--vg-skin-space-md));
  z-index: 3;
  margin-inline: 0;
  padding-block: var(--vg-skin-space-sm) var(--vg-skin-space-md);
  background: var(--vg-skin-cream);
  border-bottom: 2px solid var(--vg-skin-rim);
  box-shadow: none;
}
#vg-panel-body:has(.vg-town-tabs) { scroll-padding-top: calc(2 * var(--vg-k-h) + var(--vg-skin-space-xl)); }

/* Town > Street life number cards: the type scale of a kit row (title in the display face, value as small reading
   copy), aligned to the start like every other card, instead of dense centred bold. The cells carry inline styles from
   town-sheet.ts, so only !important can restyle them here. */
#vg-town-stats { overflow-wrap: break-word !important; font-size: var(--vg-skin-font-small) !important; }
#vg-town-stats > div {
  text-align: start !important;
  padding: var(--vg-skin-space-md) !important;
  background: var(--vg-skin-paper) !important;
  border: 2px solid var(--vg-skin-rim);
  line-height: var(--vg-skin-font-small-line);
}
/* The label is the cell's own text (first paint) or a span (repaint); the value is its <b>. */
#vg-town-stats > div {
  font-family: var(--vg-skin-font-display-family);
  font-weight: var(--vg-skin-font-display-weight);
  font-size: var(--vg-skin-font-label);
  color: var(--vg-skin-ink);
}
#vg-town-stats > div > b {
  display: block;
  margin-top: var(--vg-skin-space-xs);
  font-family: var(--vg-skin-font-body-family);
  font-size: var(--vg-skin-font-small);
  font-weight: var(--vg-skin-font-small-weight);
  line-height: var(--vg-skin-font-small-line);
  color: var(--vg-skin-ink-soft);
}
#vg-town-stats > div > br { display: none; }

/* Needs-your-attention counter: 48 px like every other text control, and its line takes two balanced lines rather than
   cutting "3 things to do" to "3 things …" in the Today card's narrow column. */
#vg-activity-head > #vg-attn.vg-k-btn, #vg-attn.vg-k-btn { min-height: 48px !important; }
/* A mouse needs no 48 px target: on desktop the Today row and its counter sit close as one head (owner, 3 Nov), at the
   44 px every kit text control keeps (test:buttons). */
@media (hover:hover) and (pointer:fine) {
  #vg-activity-head > #vg-activity-summary.vg-k-btn, #vg-activity-head > #vg-attn.vg-k-btn { min-height: 44px !important; }
}
#vg-attn [data-attn-line] {
  white-space: normal; text-overflow: clip; text-wrap-style: balance;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-height: var(--vg-skin-font-label-line);
}

/* Phone wallet: the strip keeps the game's own inset and gaps (phone-chrome.css), and its segments the 44 px the strip's
   48 px row was laid out for, so the strip never grows into the Menu button under it (spacing gate R1/R3). */
@media (max-width:960px) {
  body #vg-tr#vg-tr .vg-wallet-stats .vg-k-btn.vg-k-hud-pill { min-height: 44px !important; }
}
/* A fold placed inside a column group (resident card: "More treats" after the first four treats) takes the whole row,
   so its own buttons are not squeezed into one 78 px cell. */
.vg-k-actions:is(.vg-k-cols2,.vg-k-cols3) > details.vg-k-fold { grid-column: 1 / -1; }
/* Whole-row buttons: the indicator now fits the 16 px end, so the row keeps one 16 px inset on both sides (was 32 at
   the end). In a two-column grid of rows (Bag goods) the row title takes the label step (16 px), so a one-word good
   ("sugarcane", "medicine") fits its half of a phone row without breaking. */
button.vg-k-row-item { padding-inline-end: var(--vg-skin-space-lg); }
:is(#vg-inventory-goods,.vg-k-cols2,.vg-k-cols3) > .vg-k-row-item .vg-k-row-title,
:is(#vg-inventory-goods,.vg-k-cols2,.vg-k-cols3) > li > .vg-k-row-item .vg-k-row-title { font-size: var(--vg-skin-font-label); line-height: var(--vg-skin-font-label-line); }
#vg-inventory-goods > .vg-k-row-item { gap: var(--vg-skin-space-xs); }
#vg-inventory-goods > .vg-k-row-item > .vg-stock-art { width: 44px; height: 44px; }
/* Buttons sharing a row in a two- or three-column group: the glyph sits 4 px from its words and the label drops the
   display tracking, so a long word beside a glyph ("🌼 posy of wildflowers") fits its cell. Box, padding and type size
   stay the kind's own (test:buttons). */
.vg-k-actions:is(.vg-k-cols2,.vg-k-cols3) > .vg-k-btn > .vg-k-label { gap: var(--vg-skin-space-xs); letter-spacing: 0; }
/* A settings switch with a sub-line (Auto: "Fix food and care shortfalls" / who pays) stacks its words on the left of
   the knob instead of three side-by-side columns. */
.vg-settings .vg-k-btn.vg-switch:has(> .vg-k-sub) {
  display: grid; grid-template-columns: minmax(0,1fr) auto; column-gap: var(--vg-skin-space-md); row-gap: var(--vg-skin-space-2xs);
  align-items: center; justify-items: start; text-align: start;
}
.vg-settings .vg-k-btn.vg-switch:has(> .vg-k-sub) > :is(.vg-k-label,.vg-k-sub) { grid-column: 1; justify-content: flex-start; text-align: start; }
.vg-settings .vg-k-btn.vg-switch:has(> .vg-k-sub)::after { grid-column: 2; grid-row: 1 / span 2; }
/* A reading row with its own action (collection board: "Milk · 0 of 8 given" beside "Give 6 more from the pantry" and
   its cost line): the words keep at least 9 rem; when the action does not fit beside them it moves under them, to the
   end, instead of squeezing the words to one letter per line. */
.vg-k-row-item:has(> .vg-k-btn) { flex-wrap: wrap; }
.vg-k-row-item > .vg-k-row-text { flex: 1 1 9rem; }
.vg-k-row-item > .vg-k-btn { flex: 0 1 auto; max-width: 100%; min-width: min-content; margin-inline-start: auto; }

/* Dialog rhythm (owner, 3 Nov: "fix the spacing on dialogs like this"). A plain <details> in a sheet or dialog (the
   resident card's Suggest a hangout) stacked its summary and buttons with no gap; it now keeps the kit's 8 px rhythm and
   a 48 px summary like the kit fold. The fold and summary rules weigh nothing (:where), so a screen's own rule wins. */
:where(#vg-panel-body, .vg-k-dialog-body, dialog) :where(details:not(.vg-k-fold)) { margin-block-start: var(--vg-gap-sm); }
:where(#vg-panel-body, .vg-k-dialog-body, dialog) :where(details:not(.vg-k-fold)) > :where(summary) {
  min-height: 48px; box-sizing: border-box; padding-block: 12px; /* stays a list item: the browser keeps its open/closed marker */
  font-weight: var(--vg-skin-font-small-weight, 800); cursor: pointer;
}
/* The gap itself must beat the kit's own `.vg-k-btn { margin: 0 }`, so it carries one class of weight. */
:where(#vg-panel-body, .vg-k-dialog-body, dialog) details:not(.vg-k-fold) > * + * { margin-block-start: var(--vg-gap-sm); }
/* The kit's button reset (`.vg-k-btn.vg-k-btn:where(:not(.vg-k-hud)) { margin: 0 }`) weighs two classes; a button in a
   plain fold keeps the gap with three (spacing audit R1: Suggest a hangout's buttons touched again, 4 Nov). */
:where(#vg-panel-body, .vg-k-dialog-body, dialog) details:not(.vg-k-fold) > * + .vg-k-btn.vg-k-btn { margin-block-start: var(--vg-gap-sm); }

/* A supplier's goal note ("For Saw Planks · 4 of 6 …", Ruling 116) leads its sheet as one soft butter card. It takes focus
   only so a screen reader reads it first; it is not a control, so it shows no focus box. */
#vg-gathering-goal {
  padding: var(--vg-skin-space-md) var(--vg-skin-space-lg); margin: 0 0 var(--vg-skin-space-md);
  border-radius: 18px; background: var(--vg-skin-butter); border: 2px solid var(--vg-skin-butter-lip); color: var(--vg-skin-butter-ink);
}
#vg-gathering-goal:focus { outline: none; }
#vg-gathering-goal > h3 { margin: 0 0 var(--vg-skin-space-xs); }
#vg-gathering-goal > p { margin: 0; }

/* ===== v3.3 game feel (planner 6c575c1f "UI refinement", 4 Nov 2026; Ruling 125) =====
   The owner's ask: dialogs should read as a game, not a form. Paint only: no kit kind changes its box (test:buttons),
   no control changes its size (test:kit-fit), and decoration lives on outlines, pseudo-elements and non-control parts.
   Comparable: Animal Crossing: New Horizons (NookPhone apps and Nook Stop: a ribboned title with a round app badge,
   stitched paper cards, fat rounded meters, price tags as badges). */

/* 1. Sheet and dialog titles: a ribbon with a lip, its icon in a round medallion that sits proud of the ribbon. */
#vg-panel#vg-panel #vg-panel-title, .vg-dialog-header > .vg-k-title {
  position: relative;
  border-radius: 26px 18px 18px 26px;
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 3px 0 var(--vg-skin-mint-lip);
  text-shadow: 0 1px 0 var(--vg-skin-highlight);
}
#vg-panel-title > svg.vg-i:first-child, .vg-dialog-header > .vg-k-title > svg.vg-i:first-child {
  box-sizing: content-box; width: .95em; height: .95em; padding: 7px; margin: -10px 6px -10px -10px;
  vertical-align: middle; border-radius: 50%;
  background: var(--vg-skin-butter); color: var(--vg-skin-butter-ink);
  border: 3px solid var(--vg-skin-paper);
  box-shadow: 0 3px 0 var(--vg-skin-butter-lip);
}
/* The rule under the head is stitched, like the seam of a cloth pouch. */
#vg-panel#vg-panel #vg-panel-head { border-bottom: 2px dashed var(--vg-skin-rim) !important; }

/* 2. Stitched paper: an outer card shows a dashed seam just inside its edge (an outline, so no box changes). Nested
   cards stay plain; the seam never takes a focus ring's place (cards are not controls). */
.vg-k-card.vg-dialog-card, .vg-dialog-content .vg-dialog-card {
  outline: 2px dashed color-mix(in srgb, var(--vg-skin-rim) 85%, transparent);
  outline-offset: -8px;
}
.vg-k-card .vg-k-card, .vg-dialog-card .vg-dialog-card, .vg-dialog-card.vg-dialog-card:focus-visible { outline: none; }
/* Section breaks inside a sheet: dashed seams instead of hairlines. */
:where(#vg-panel-body, .vg-k-dialog-body, dialog) hr {
  border: 0; border-top: 2px dashed var(--vg-skin-rim); margin-block: var(--vg-skin-space-md); height: 0; background: none;
}

/* 3. Progress as fat, striped meters with a lip (Hall build, research, scouting, packing, mastery). */
:where(#vg-panel, dialog) progress {
  -webkit-appearance: none; appearance: none; display: block; box-sizing: border-box;
  height: 18px; margin-block: var(--vg-skin-space-xs) var(--vg-skin-space-sm);
  border: 2px solid var(--vg-skin-rim); border-radius: 999px; overflow: hidden;
  background: var(--vg-skin-muted); color: var(--vg-skin-green-lip);
  box-shadow: inset 0 2px 0 #51433612;
}
:where(#vg-panel, dialog) progress::-webkit-progress-bar { background: var(--vg-skin-muted); border-radius: 999px; }
:where(#vg-panel, dialog) progress::-webkit-progress-value {
  border-radius: 999px;
  background: repeating-linear-gradient(-45deg, var(--vg-skin-green) 0 8px, #d7efcb 8px 16px);
  box-shadow: inset 0 -3px 0 var(--vg-skin-green-lip), inset 0 2px 0 var(--vg-skin-highlight);
}
:where(#vg-panel, dialog) progress::-moz-progress-bar {
  border-radius: 999px;
  background: repeating-linear-gradient(-45deg, var(--vg-skin-green) 0 8px, #d7efcb 8px 16px);
  box-shadow: inset 0 -3px 0 var(--vg-skin-green-lip);
}

/* 4. Facts as chips and tags, not "Label: value" lines. The work status ("Hall 21 · 4 min construction at 1×") is a sky
   chip with a lip; a bill or reward ("Construction bill: …") is a butter price tag with a stitched seam. */
.vg-dialog-content .vg-work-status, #vg-panel-body .vg-work-status {
  padding: var(--vg-skin-space-xs) var(--vg-skin-space-md); border-radius: 999px;
  background: var(--vg-skin-sky); color: var(--vg-skin-sky-ink);
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 3px 0 var(--vg-skin-sky-lip);
  font-family: var(--vg-skin-font-display-family); font-weight: var(--vg-skin-font-display-weight); letter-spacing: var(--vg-skin-font-display-tracking);
}
.vg-dialog-content .vg-work-reward, #vg-panel-body .vg-work-reward {
  padding: var(--vg-skin-space-md) var(--vg-skin-space-lg);
  background: var(--vg-skin-butter); color: var(--vg-skin-butter-ink);
  border-radius: 18px; box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 3px 0 var(--vg-skin-butter-lip);
  outline: 2px dashed color-mix(in srgb, var(--vg-skin-butter-lip) 70%, transparent); outline-offset: -6px;
}
/* The placement review's bill is the price tag of what you are about to build. */
#vg-panel-body .vg-review-bill {
  padding: var(--vg-skin-space-md) var(--vg-skin-space-lg); margin-block: var(--vg-skin-space-sm);
  background: var(--vg-skin-butter); color: var(--vg-skin-butter-ink); border-radius: 18px;
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 3px 0 var(--vg-skin-butter-lip);
  outline: 2px dashed color-mix(in srgb, var(--vg-skin-butter-lip) 70%, transparent); outline-offset: -6px;
}
#vg-panel-body .vg-review-bill > b { font-family: var(--vg-skin-font-display-family); font-weight: var(--vg-skin-font-display-weight); letter-spacing: var(--vg-skin-font-display-tracking); }
/* kit.stat(): a fact chip, small label over a display-face value (Buy goods: price tag, Wallet, Barn). A run of chips
   wraps whole with the 8 px rhythm. */
:where(p, div):has(> .vg-k-stat) { display: flex; flex-wrap: wrap; align-items: stretch; gap: var(--vg-skin-space-sm); }
.vg-k-stat {
  display: inline-flex; flex-direction: column; justify-content: center; gap: 0;
  padding: var(--vg-skin-space-xs) var(--vg-skin-space-md); border-radius: 14px;
  background: var(--vg-skin-paper); color: var(--vg-skin-ink); border: 2px solid var(--vg-skin-rim);
  box-shadow: 0 2px 0 var(--vg-skin-rim);
}
.vg-k-stat > small { font-size: var(--vg-skin-font-counter); font-weight: var(--vg-skin-font-small-weight); color: var(--vg-skin-ink-soft); line-height: 1.2; }
.vg-k-stat > b {
  display: inline-flex; align-items: center; gap: var(--vg-skin-space-xs); white-space: nowrap;
  font-family: var(--vg-skin-font-display-family); font-weight: var(--vg-skin-font-display-weight); letter-spacing: var(--vg-skin-font-display-tracking);
  font-variant-numeric: tabular-nums; line-height: 1.25;
}
.vg-k-stat-butter { background: var(--vg-skin-butter); color: var(--vg-skin-butter-ink); border-color: var(--vg-skin-butter-lip); box-shadow: 0 2px 0 var(--vg-skin-butter-lip); }
.vg-k-stat > b > .vg-i-lead { margin: 0; }
/* A row's count or price (meta) is a badge: display face, lip, never wraps. */
.vg-k-row-item .vg-k-row-meta {
  box-shadow: inset 0 2px 0 var(--vg-skin-highlight), 0 2px 0 var(--vg-skin-mint-lip);
  white-space: nowrap;
}

/* 5. Tactile tiles: the Build catalog's price sits on a butter tag; a recipe card's art is a large round token with a
   lip, and its plan badge carries a lip too. */
.vg-dialog-content .vg-build-tile .vg-tile-price {
  padding: 2px var(--vg-skin-space-md); border-radius: 999px;
  background: var(--vg-skin-butter); color: var(--vg-skin-butter-ink);
  box-shadow: 0 2px 0 var(--vg-skin-butter-lip);
  font-family: var(--vg-skin-font-display-family); font-weight: var(--vg-skin-font-display-weight); letter-spacing: var(--vg-skin-font-display-tracking);
}
.vg-dialog-content .vg-build-tile.is-locked .vg-tile-price { background: var(--vg-skin-muted); color: var(--vg-skin-muted-ink); box-shadow: none; font-family: var(--vg-skin-font-body-family); }
.vg-build-vignette { outline: 2px dashed color-mix(in srgb, var(--vg-skin-rim) 70%, transparent); outline-offset: -5px; }
.vg-recipe-art {
  flex-basis: 52px !important; height: 52px !important; border-radius: 50% !important;
  border: 3px solid var(--vg-skin-paper); box-shadow: 0 3px 0 var(--vg-skin-butter-lip);
}
.vg-recipe-plan { box-shadow: 0 2px 0 var(--vg-skin-mint-lip); }

/* 6. The speaker card's name tag (builders, advisor) gets the ribbon lip of the titles. */
.vg-work-speaker > div > strong { border-color: var(--vg-skin-butter-lip); background: var(--vg-skin-butter); color: var(--vg-skin-butter-ink); box-shadow: 0 2px 0 var(--vg-skin-butter-lip); }
.vg-work-speaker > div { border-color: var(--vg-skin-rim); background: var(--vg-skin-paper); }

/* 7. Settings rows: the row's icon sits in a small sky medallion (inside the row's own height), and a group name
   ("Play your way", "Related") runs into a stitched seam instead of floating as a bare label. */
.vg-settings > details > summary[data-settings-row] > span:first-child > svg.vg-i:first-child {
  box-sizing: border-box; width: 32px; height: 32px; min-width: 32px; padding: 6px; margin-block: -6px; margin-inline-end: 4px;
  border-radius: 50%; background: var(--vg-skin-sky); color: var(--vg-skin-sky-ink); box-shadow: 0 2px 0 var(--vg-skin-sky-lip);
}
.vg-settings [data-settings-group], .vg-nav-related-title {
  display: flex; align-items: center; gap: var(--vg-skin-space-sm);
  font-family: var(--vg-skin-font-display-family); font-weight: var(--vg-skin-font-display-weight); letter-spacing: var(--vg-skin-font-display-tracking);
  color: var(--vg-skin-ink-soft);
}
.vg-settings [data-settings-group]::after, .vg-nav-related-title::after {
  content: ''; flex: 1 1 auto; height: 0; border-top: 2px dashed var(--vg-skin-rim);
}
