/* Comic shop site — site styles
   Mobile-first: base rules target phones; wider layouts are layered on with
   min-width breakpoints. Dark "Bronze Age Modern + Dusty Blue" theme.
   The --brand-* colors and the --font-* fonts come from Shop Settings (js/theme-vars.js themeCss: the site Worker
   writes them into each page's <head>, and js/site.js keeps them current);
   every other color is derived from them below, or is a fixed semantic color (links, errors, success).
   The staff admin has its own stylesheet (admin/base.css + admin/admin.css).
   Breakpoints: min-width 480 / 600 / 700 / 800 / 1100px, max-width one under a min step (479 / 599 / 699 / 799 / 1099px), and
   (max-width: 599px) in scripts. css/site.test.js rejects any other width.
   Spacing, text sizes, corners, shadows, layers (z-index) and durations are steps in :root; the test rejects bare ones,
   and every animation needs a prefers-reduced-motion rule that stops or slows it. */

/* Fonts are served from this site (fonts/), Latin subset only, so no request goes to Google before the page can draw. */
@font-face { font-family: 'Archivo Black'; font-style: normal; font-weight: 400; font-display: swap; src: url(../fonts/archivo-black-latin.woff2) format('woff2'); }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 600 800; font-display: swap; src: url(../fonts/archivo-latin.woff2) format('woff2'); }
@font-face { font-family: 'Source Sans 3'; font-style: normal; font-weight: 400 700; font-display: swap; src: url(../fonts/source-sans-3-latin.woff2) format('woff2'); }

:root {
  color-scheme: dark;

  /* Shop Settings → Logo, Colors & Fonts. These are the defaults used if settings can't be read. */
  --brand-primary: #982c21;   /* buttons (white text on this is 7:1) */
  --brand-accent: #e7b84b;    /* gold: banner, badges, highlights */
  --brand-ink: #f4f0ea;       /* text */
  --brand-paper: #121212;     /* page background */
  --brand-footer: #121212;
  --on-primary: #fff;         /* text on the main color; applyTheme switches it to dark for light colors */
  --on-accent: #161616;       /* text on the accent (gold) fills; applyTheme switches it to white for a dark accent */
  --gold-text: var(--gold);   /* the accent as text or an edge; applyTheme darkens (or lightens) it until it reads on the page */
  --footer-text: var(--muted);
  --footer-heading: var(--brand-accent);
  --footer-link: var(--teal);
  --footer-link-hover: var(--teal-hover);

  --ink: var(--brand-ink);
  --paper: var(--brand-paper);
  --gold: var(--brand-accent);
  --red-btn: var(--brand-primary);
  --red-btn-hover: color-mix(in srgb, var(--brand-primary) 85%, black);
  --red: color-mix(in srgb, var(--brand-primary) 55%, #ff5a3d);   /* card top rule */

  /* Neutrals: the text color mixed into the page background */
  --surface: color-mix(in srgb, var(--paper), var(--ink) 4%);
  --raised: color-mix(in srgb, var(--paper), var(--ink) 9%);
  --line: color-mix(in srgb, var(--paper), var(--ink) 17%);        /* soft divider */
  --field-line: color-mix(in srgb, var(--paper), var(--ink) 52%);  /* form-field outline, >=3:1 for accessibility */
  --muted: color-mix(in srgb, var(--paper), var(--ink) 76%);

  /* Links and focus, feedback and a cream for headings: set for this dark page; applyTheme swaps them
     (and color-scheme) for readable ones when Shop Settings picks a light page background. */
  --cream: #e9e1d3;
  --teal: #91bbdd;
  --teal-hover: #a5c9e5;
  --teal-dark: #182630;
  --error: #ff9585;
  --ok: #9bd7ae;
  --warn: #f0a35a;           /* Low Stock badge, staff orange text */
  --clearance: #f4b6be;      /* Clearance badge */
  --violet: #cdb6ee;         /* staff purple text */
  --sold-out: #3a3632;       /* Sold Out badge, a dark chip on any page, with --on-sold-out text */
  --on-sold-out: #d6cdbf;
  --swipe-remove: #b3261e;    /* the Remove a swipe uncovers in the app's My List: the same red on every page */
  --on-swipe-remove: #fff;    /* its label (6.5:1) */
  --focus: var(--teal);

  --font-display: 'Archivo Black', 'Arial Black', sans-serif;
  --font-heading: 'Archivo', Arial, sans-serif;
  --font-body: 'Source Sans 3', system-ui, sans-serif;
  --display-weight: 400;       /* headline font's weight, spacing and case: Shop Settings → Fonts may change them */
  --display-tracking: -.045em;
  --display-case: uppercase;
  --heading-tracking: 0em;     /* sub-heading and body letter spacing (Shop Settings → Fonts: Tight / Wide) */
  --body-tracking: 0em;
  --display-scale: 1;          /* text size of each font slot (Shop Settings → Fonts: Small / Large) */
  --heading-scale: 1;
  --body-scale: 1;

  --radius: 5px;
  --border: 1px solid var(--line);
  --shadow: none;
  --shadow-lg: 0 10px 40px rgb(0 0 0 / .6);
  --field-h: 46px;      /* every input, select and search box, and a button */
  --tap: 44px;          /* the smallest touch target: links and toggles on their own, icon buttons, small buttons on phones */
  --btn-h-sm: 36px;     /* a small button (.btn--small) on wider screens; --tap on phones */
  --gutter: 16px;
  --max: 1180px;

  /* Type roles below the page title (h1) and section heading (h2): use these instead of one-off sizes. */
  --fs-title: calc(1.25rem * var(--heading-scale));   /* panel, month, post and dialog titles */
  --fs-sub: calc(1.1rem * var(--heading-scale));      /* sub-headings: h3, group headings, footer headings */
  --fs-compact: calc(1rem * var(--heading-scale));    /* titles inside dense lists */
  --space-block: 24px;   /* gap under a page title block */

  /* Spacing scale, named by pixels (the admin's scale, plus 96 for the desktop hero). Use these for margin, padding
     and gap instead of bare numbers; css/site.test.js rejects a bare px or rem. */
  --sp-2: 2px;  --sp-4: 4px;  --sp-6: 6px;  --sp-8: 8px;  --sp-10: 10px;  --sp-12: 12px;  --sp-14: 14px;
  --sp-16: 16px;  --sp-20: 20px;  --sp-24: 24px;  --sp-32: 32px;  --sp-40: 40px;  --sp-64: 64px;  --sp-96: 96px;
  --list-bar-h: 76px;    /* the pull-list bar at the foot of the screen; the page leaves this much room under it */
  --tab-bar-h: 60px;     /* the pull list app's tab bar (app.html), not counting the phone's home-bar inset */
  --app-bar-h: 60px;     /* the pull list app's header bar, under the phone's status bar */
  --app-header-bottom: calc(var(--app-bar-h) + env(safe-area-inset-top) + 1px); /* the app's header with its edge: what sits under it starts here */
  --swipe-open: 88px;    /* the Remove a short swipe leaves showing on a My List row (js/app-swipe.js reads it) */

  /* Text sizes outside the headline, sub-heading and body scales above (which follow Shop Settings → Fonts).
     The same steps as the admin's where they overlap. */
  --fs-3xs: .6rem;       /* inside a cover: "Top" on the Top 10 disc, a missing cover's name */
  --fs-2xs: .72rem;      /* badges, chips, small labels */
  --fs-xs: .8rem;        /* meta lines on cards, FOC, the copyright line */
  --fs-sm: .85rem;       /* hints, notes, the announcement */
  --fs-ui: .9rem;        /* dense UI: search box, counts, small links */
  --fs-md: .95rem;       /* field labels, list text */
  --fs-base: 1rem;
  --fs-btn: .875rem;     /* button labels and the menu (14px) */
  --fs-lede: 1.1rem;     /* intro text, the × on close buttons */
  --fs-num-sm: 1.2rem;   /* small date and Top 10 numbers */
  --fs-num: 1.35rem;     /* the Top 10 number */

  /* Corners. --radius (5px) is panels, cards, filters and maps. */
  --radius-xs: 2px;      /* badges and chips */
  --radius-sm: 3px;      /* buttons, thumbnails */
  --radius-lg: 8px;      /* dialogs and the open multi-select */
  --radius-field: 9px;   /* inputs, selects, the search box */
  --radius-pill: 999px;  /* count badges and pills */

  /* Shadows besides --shadow / --shadow-lg (dialogs). */
  --shadow-menu: 0 12px 24px rgb(0 0 0 / .5);              /* the open phone menu */
  --shadow-badge: 0 2px 6px rgb(0 0 0 / .4);               /* the Top 10 disc on a cover */
  --shadow-focus: 0 0 0 3px color-mix(in srgb, var(--focus) 20%, transparent);   /* glow round a focused field */

  /* Stacking order, lowest first. Use these instead of a bare z-index; css/site.test.js rejects one. */
  --z-raised: 1;         /* above the rest of its card (the Top 10 disc) */
  --z-popover: 30;       /* an open multi-select panel */
  --z-bar: 40;           /* the pull-list bar at the foot of the screen */
  --z-chat: 60;          /* the live chat button and box: over the sticky header and the pull-list bar, under the skip link */
  --z-header: 50;        /* the sticky site header and its menu */
  --z-skip: 100;         /* the skip link, above everything it jumps over */
  --z-busy: 9998;        /* the loading dimmer; its spinner sits one above */
  --z-splash: 10000;     /* the pull list app's loading screen, over everything while it opens */

  /* Motion. Every transition stops and the skeleton stops pulsing under prefers-reduced-motion; the spinner slows. */
  --dur-press: .08s;     /* a button's press */
  --dur: .15s;           /* hovers, the menu icon, a fold's arrow */
  --dur-slide: .22s;     /* the app's search sliding down from under the header */
  --dur-sheet: .28s;     /* the title dialog sliding up or down as a sheet on a phone */
  --ease-sheet: cubic-bezier(.2, .8, .2, 1); /* a sheet or panel arriving: quick, then settling */

  /* A press, in the app: what a control does under the finger (no grey tap flash there). */
  --press-scale: .97;    /* a button shrinks a little */
  --press-scale-icon: .85; /* a tab's icon shrinks more */
  --press-dim: brightness(.85); /* a button or cover darkens */
  --press-fade: .6;      /* a link-style button fades */
  --dur-spin: .7s;       /* one turn of the loading spinner */
  --dur-spin-calm: 2s;   /* the spinner under prefers-reduced-motion */
  --dur-pulse: 1.2s;     /* the loading skeleton's pulse */
  --dur-splash-max: 4s;  /* the app's loading screen fades by itself after this, even if no script runs */
}
*,
*::before,
*::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
[hidden] { display: none !important; }
body {
  margin: 0;
  font: var(--fs-base)/1.55 var(--font-body);
  letter-spacing: var(--body-tracking);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  font-size: calc(18px * var(--body-scale));
  line-height: 1.5;
  background: var(--paper);
  color: var(--ink);
}
main { flex: 1; }
img { max-width: 100%; height: auto; display: block; }
a { color: var(--teal); }
/* Links to a page the shop switched off (Admin → Pages; js/optional-pages.js), wherever they are: page text, the home
   page's Directions button. js/site.js lists the off pages' slugs in <html data-off>. */
[data-off~="about"] a[href="about.html"], [data-off~="visit"] a[href="contact.html"],
[data-off~="we-buy-comics"] a[href="we-buy-comics.html"], [data-off~="gift-cards"] a[href="gift-cards.html"],
[data-off~="how-to"] a[href="how-to.html"], [data-off~="faq"] a[href="faq.html"],
[data-off~="calendar"] a[href="calendar.html"], [data-off~="calendar"] a[href^="event.html"],
[data-off~="news"] a[href="blog.html"], [data-off~="news"] a[href^="post.html"],
[data-off~="calendar"] .home-events, [data-off~="news"] .home-news,
[data-off~="calendar"][data-off~="news"] .home-upcoming { display: none; }
/* A link-button reads as a link, so it's underlined the same way. */
a, .link-button { text-decoration-thickness: 2px; text-underline-offset: 5px; }
a:hover { color: var(--teal-hover); }
:focus-visible { outline: 3px solid var(--teal); outline-offset: 3px; }
/* A heading that a script focuses (tabindex="-1": the app's view titles when a tab opens, Coming Up after a redraw,
   the app's results count after Hot's See all)
   is there so screen readers start reading from it. It isn't a control, so it gets no ring. */
:is(h1, h2, h3, .results-count)[tabindex="-1"]:focus { outline: none; }
h1, h2, h3 { font-family: var(--font-display); font-weight: var(--display-weight); line-height: 1.15; margin: 0 0 .5em; letter-spacing: .01em; }
h1 { font-size: calc(clamp(34px, 5vw, 64px) * var(--display-scale)); line-height: .96; letter-spacing: var(--display-tracking); text-transform: var(--display-case); margin: var(--sp-14) 0 var(--sp-16); }
h2 { font-family: var(--font-heading); font-weight: 700; font-size: calc(1.5rem * var(--heading-scale)); line-height: 1.2; letter-spacing: var(--heading-tracking); }
h3 { font-size: var(--fs-sub); font-family: var(--font-heading); font-weight: 700; letter-spacing: var(--heading-tracking); }
p { margin: 0 0 1em; }
.container { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.section { padding-block: var(--sp-32); }
.section--alt { background: var(--surface); }
.section__head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--sp-8) var(--sp-16); margin-bottom: var(--space-block); }
.section__head h1, .section__head h2 { margin: 0; }
.section__links { display: flex; flex-wrap: wrap; gap: var(--sp-4) var(--sp-20); margin: 0; }
.lede { font-size: var(--fs-lede); max-width: 84ch; margin-bottom: 4em; color: var(--muted); }
.lede > :last-child, .page-body > :last-child { margin-bottom: 0; }
/* Staff-edited rich text (admin WYSIWYG): a quote block shows as a callout box. */
.lede blockquote, .page-body blockquote, #faq-list blockquote {
  margin: 1em 0;
  padding: var(--sp-10) var(--sp-12);
  font-weight: 700;
  border-radius: var(--radius);
  background: var(--gold);
  color: var(--on-accent);
}
.page-body { margin-bottom: var(--sp-20); }
.page-body ul, .page-body ol { padding-left: 1.4em; }
.page-body li { margin-bottom: .35em; }
.prose { max-width: 960px; }
.prose h2 { margin-top: 1.5em; }
/* Formatting from the admin editor (page text, news, events, FAQ) */
.ql-align-center { text-align: center; }
.ql-align-right { text-align: right; }
.ql-align-justify { text-align: justify; }
.ql-indent-1 { padding-left: 2em; }
.ql-indent-2 { padding-left: 4em; }
.ql-indent-3 { padding-left: 6em; }
.prose img, [data-content] img, #faq-list img { max-width: 100%; height: auto; border-radius: var(--radius); }
.prose .ql-align-center img, [data-content] .ql-align-center img { margin-inline: auto; }
iframe.ql-video { display: block; width: 100%; max-width: 640px; aspect-ratio: 16 / 9; height: auto; border: 0; border-radius: var(--radius); margin: 1em 0; }
.ql-align-center iframe.ql-video, iframe.ql-video.ql-align-center { margin-inline: auto; }
.prose hr, [data-content] hr, #faq-list hr { border: 0; border-top: 2px solid var(--line); margin: 1.5em 0; }
.prose h4 { font-size: var(--fs-base); margin-top: 1.2em; }
/* Image alignment and size set in the editor (width is an inline percentage) */
.img-align-left { float: left; margin: .3em 1.2em .8em 0; }
.img-align-right { float: right; margin: .3em 0 .8em 1.2em; }
.img-align-center { display: block; margin: 1em auto; }
.prose::after, [data-content]::after, #faq-list details > div::after, .ql-editor::after { content: ''; display: table; clear: both; }
.prose h2, .prose h3, .prose h4, .prose hr, .prose table, iframe.ql-video { clear: both; }
@media (max-width: 599px) {
  /* Phones: no text wrapping beside pictures, and small pictures get room to be seen. */
  .prose img, [data-content] img, #faq-list img { float: none; display: block; margin: 1em auto; min-width: min(60%, 100%); }
}
/* Tables from the editor */
.prose table, [data-content] table, #faq-list table { border-collapse: collapse; margin: 1em 0; font-size: var(--fs-md); }
.prose td, .prose th, [data-content] td, #faq-list td { border: 1px solid var(--line); padding: var(--sp-8) var(--sp-10); vertical-align: top; text-align: left; background: var(--surface); }
.prose tr:first-child td { font-weight: 700; background: var(--raised); }
@media (max-width: 599px) {
  .prose table, [data-content] table, #faq-list table { display: block; overflow-x: auto; max-width: 100%; }
}
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.skip-link {
  position: absolute;
  left: 8px;
  top: -60px;
  padding: var(--sp-8) var(--sp-12);
  z-index: var(--z-skip);
  background: var(--paper);
  color: var(--ink);
  outline: 3px solid var(--teal);
}
.skip-link:focus { top: 8px; }
/* Bar at the very top: announcements on the left, site search on the right. */
.topbar { background: var(--red-btn-hover); color: var(--on-primary); border-bottom: 1px solid color-mix(in srgb, var(--brand-primary) 70%, black); }
.topbar__inner { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--sp-4) var(--sp-12); padding-block: var(--sp-8); }
.topbar__notice { flex: 1 1 240px; margin: 0; line-height: 1.3; color: var(--on-primary); font-size: var(--fs-sm); }
.topbar__notice a { text-decoration: underline; color: inherit; font-weight: 700; }
.topbar__notice strong { text-transform: uppercase; font-size: var(--fs-2xs); color: inherit; letter-spacing: .1em; }
.topbar__search { display: flex; align-items: stretch; gap: var(--sp-4); margin-left: auto; flex: 0 1 220px; }
.topbar__search input {
  flex: 1;
  min-width: 0;
  height: 32px;
  min-height: 0;
  padding: 0 var(--sp-10);
  font: inherit;
  font-size: var(--fs-ui);
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--field-line);
  border-radius: var(--radius-field);
}
.topbar__btn {
  flex: none;
  width: 32px;
  height: 32px;
  min-height: 0;
  display: grid;
  place-items: center;
  border: 0;
  cursor: pointer;
  background: var(--gold);
  color: var(--on-accent);
  border-radius: var(--radius-field);
}
.topbar__btn:hover { filter: none; background: color-mix(in srgb, var(--gold), white 25%); }
.demo-banner { margin: 0; padding: var(--sp-6) var(--gutter); font-size: var(--fs-sm); text-align: center; background: var(--gold); color: var(--on-accent); }
/* ---------- Buttons & forms ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-6);
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--dur-press), box-shadow var(--dur-press), filter var(--dur-press);
  min-height: var(--field-h);
  padding: var(--sp-10) var(--sp-20);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  box-shadow: none;
  background: var(--teal);
  color: var(--paper);
  font: 700 var(--fs-btn)/1 var(--font-body);
  letter-spacing: .04em;
  text-transform: uppercase;
}
.btn:hover { background: var(--teal-hover); color: var(--paper); transform: none; filter: none; box-shadow: none; }
.btn:active { transform: none; box-shadow: none; }
.btn--primary { background: var(--red-btn); color: var(--on-primary); }
.btn--primary:hover { background: var(--red-btn-hover); color: var(--on-primary); }
.btn--ghost { background: transparent; color: var(--gold-text); border-color: var(--gold-text); box-shadow: none; }
.btn--ghost:hover { background: var(--raised); color: var(--gold-text); box-shadow: none; }
/* Compact, for a row of actions beside each result in a list (search's Series and Artists). On a phone it's still
   a full touch target tall; it stays narrower and quieter than a .btn. */
.btn--small { min-height: var(--btn-h-sm); padding: var(--sp-6) var(--sp-12); font-size: var(--fs-xs); }
@media (max-width: 599px) {
  .btn--small { min-height: var(--tap); }
}
/* An icon leading the label (btnIcon in js/util.js), in the label's color. */
.btn__icon { flex: none; width: 16px; height: 16px; margin-left: calc(-1 * var(--sp-2)); fill: none; stroke: currentColor; stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; }
.btn[disabled] {
  cursor: not-allowed;
  transform: none;
  opacity: 1;
  background: var(--raised);
  color: var(--muted);
  border-color: var(--line);
  box-shadow: none;
}
label, .label { display: block; font-weight: 600; font-size: var(--fs-md); margin-bottom: var(--sp-8); }
input, select, textarea {
  width: 100%;
  padding: 0 var(--sp-12);
  font: inherit;
  line-height: 1.2;
  -webkit-appearance: none;
  appearance: none;
  background-color: var(--paper);
  color: var(--ink);
  border: 1px solid var(--field-line);
  border-radius: var(--radius-field);
}
/* Text inputs, search, number and select all share one height. */
input, select { height: var(--field-h); }
textarea { padding: var(--sp-10) var(--sp-12); min-height: calc(var(--field-h) * 2); }
input[type='search']::-webkit-search-decoration { -webkit-appearance: none; }
select {
  padding-right: var(--sp-32); cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23444' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
}
input:hover, select:hover, textarea:hover { border-color: var(--teal); }
input[type='checkbox'], input[type='radio'] {
  -webkit-appearance: auto;
  appearance: auto;
  margin: 0;
  padding: 0;
  flex: none;
  cursor: pointer;
  width: 24px;
  height: 24px;
  accent-color: var(--teal);
}
.field { margin-bottom: var(--sp-14); }
.field__hint { font-size: var(--fs-sm); color: var(--muted); margin-top: var(--sp-4); }
.form-error { font-weight: 700; color: var(--error); }
.btn--block { width: 100%; }
.form-actions { display: flex; flex-wrap: wrap; gap: var(--sp-12); }
/* Margin helpers for markup written by page scripts; they win over .prose headings. */
.mt-0 { margin-top: 0 !important; }
.mt-1em { margin-top: 1em !important; }
/* ---------- Header / nav ---------- */
/* Until the script fills the header, hold its usual height (with the search bar, and the announcement wrapped on phones). */
#site-header:empty { min-height: 126px; }
@media (max-width: 479px) { #site-header:empty { min-height: 165px; } }
#site-header { position: sticky; top: 0; z-index: var(--z-header); background: var(--paper); box-shadow: none; border-bottom: 1px solid var(--line); }
.header__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); min-height: 76px; }
.brand { text-decoration: none; display: flex; align-items: center; gap: var(--sp-10); }
.brand__name { font-family: var(--font-display); font-weight: var(--display-weight); line-height: 1.1; font-size: calc(1.5rem * var(--display-scale)); letter-spacing: var(--display-tracking); color: var(--cream); }
.brand__logo { max-height: 48px; width: auto; }
.nav-toggle {
  width: var(--tap);
  height: var(--tap);
  border: 0;
  cursor: pointer;
  display: grid;
  place-items: center;
  background: var(--gold);
  border-radius: var(--radius-sm);
}
.nav-toggle__icon, .nav-toggle__icon::before, .nav-toggle__icon::after {
  display: block;
  width: 20px;
  height: 2px;
  position: relative;
  transition: transform var(--dur);
  background: var(--on-accent);
}
.nav-toggle__icon::before, .nav-toggle__icon::after { content: ''; position: absolute; left: 0; }
.nav-toggle__icon::before { top: -6px; }
.nav-toggle__icon::after { top: 6px; }
.nav-open .nav-toggle__icon { background: transparent; }
.nav-open .nav-toggle__icon::before { transform: translateY(6px) rotate(45deg); }
.nav-open .nav-toggle__icon::after { transform: translateY(-6px) rotate(-45deg); }
.nav {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  background: var(--surface);
  box-shadow: var(--shadow-menu);
  border-bottom: 1px solid var(--line);
}
.nav-open .nav { display: block; }
/* The open menu never runs past the bottom of the screen (phone held sideways, zoomed in): it scrolls instead.
   --nav-top is the header's bottom edge, measured by js/site.js when the menu opens. */
@media (max-width: 1099px) {
  .nav-open .nav {
    max-height: calc(100vh - var(--nav-top, 126px));
    max-height: calc(100dvh - var(--nav-top, 126px));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}
.nav ul { list-style: none; margin: 0; padding: var(--sp-8) var(--gutter) var(--sp-16); }
.nav a {
  display: block;
  padding: var(--sp-12) var(--sp-4);
  font-weight: 700;
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  color: var(--cream);
  font-size: var(--fs-btn);
}
.nav a[aria-current='page'] { color: var(--gold-text); text-decoration: underline; text-decoration-thickness: 2px; }
.nav-badge {
  display: inline-block;
  min-width: 1.5em;
  padding: 0 .45em;
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  line-height: 1.5em;
  text-align: center;
  vertical-align: 1px;
  background: var(--red-btn);
  color: var(--on-primary);
}
.nav a[aria-current='page'] .nav-badge { background: var(--gold); color: var(--on-accent); }
.nav-badge--new, .nav a[aria-current='page'] .nav-badge--new { background: var(--gold); color: var(--on-accent); font-weight: 700; }
/* Eight menu links plus the logo need ~1000px; below 1100px the menu stays behind the button. */
@media (min-width: 1100px) {
  .nav-toggle { display: none; }
  #site-header { box-shadow: none; }
  .nav { display: block; position: static; background: none; box-shadow: none; border: 0; }
  .nav ul { display: flex; gap: var(--sp-4); padding: 0; }
  .nav a { padding: var(--sp-8) var(--sp-10); border: 0; min-height: var(--tap); display: inline-flex; align-items: center; border-radius: 0; }
  .nav a[aria-current='page'] { background: none; color: var(--gold-text); }
}
/* ---------- Footer ---------- */
#site-footer { padding-top: var(--sp-32); background: var(--brand-footer); border-top: 1px solid var(--line); color: var(--footer-text); }
#site-footer a { color: var(--footer-link); }
#site-footer a:hover { color: var(--footer-link-hover); }
#site-footer :focus-visible { outline-color: var(--footer-link); }
.footer__grid { display: grid; gap: var(--sp-24); }
.footer__heading { font-family: var(--font-heading); font-size: calc(.8rem * var(--heading-scale)); letter-spacing: .14em; text-transform: uppercase; color: var(--footer-heading); }
.footer__heading--next { margin-top: var(--sp-20); }
.footer__links { list-style: none; padding: 0; margin: 0 0 var(--sp-12); columns: 2; column-gap: var(--sp-24); }
.footer__links li { margin-bottom: var(--sp-6); break-inside: avoid; overflow-wrap: anywhere; } /* a long page title wraps instead of widening the page */
.footer__legal { padding-block: var(--sp-20); margin: 0 auto; text-align: center; font-size: var(--fs-xs); }
address { font-style: normal; margin-bottom: 1em; }
/* Social icons (footer, Visit page): 44px tap targets, current text color. */
.socials { list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-6); padding: 0; margin: var(--sp-12) 0; }
.socials a {
  display: grid;
  place-items: center;
  width: var(--tap);
  height: var(--tap);
  border-radius: 50%;
  color: inherit;
  transition: background var(--dur), color var(--dur);
  background: rgb(255 255 255 / .08);
}
.socials a:hover { background: var(--red-btn); color: var(--on-primary); }
.socials svg { width: 20px; height: 20px; fill: currentColor; }
/* Footer: plain icons (no circles), row pulled left so the first glyph lines up
   with the text above; each link keeps its 44px tap area. */
#site-footer .socials { gap: 0; margin-left: -12px; }
#site-footer .socials a { background: none; }
#site-footer .socials a:hover { background: none; color: var(--footer-link-hover); }
@media (min-width: 700px) {
  .footer__grid { grid-template-columns: repeat(3, 1fr); }
}
.footer__location { margin: 0 0 var(--sp-12); }
.footer__sub { font-size: var(--fs-md); margin: var(--sp-12) 0 var(--sp-4); }
.locations-grid { display: grid; gap: var(--sp-20); }
@media (min-width: 800px) { .locations-grid { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); } }
.location .map { margin-bottom: 0; }
.hours { margin: 0; }
.hours div { display: flex; justify-content: space-between; gap: var(--sp-16); max-width: 280px; }
.hours dt { font-weight: 700; }
.hours dd { margin: 0; }
/* ---------- Hero ---------- */
.hero {
  padding-block: var(--sp-64);
  border-bottom: 1px solid var(--line);
  background:
    linear-gradient(color-mix(in srgb, var(--paper) 88%, transparent), color-mix(in srgb, var(--paper) 88%, transparent)),
    radial-gradient(#ffffff14 1px, transparent 1px) 0 0 / 7px 7px,
    var(--paper);
}
/* Banner photo: a dark overlay keeps the headline readable on any picture. */
.hero.hero--photo {
  color: var(--ink);
  background:
    linear-gradient(90deg, color-mix(in srgb, var(--paper) 92%, transparent), color-mix(in srgb, var(--paper) 78%, transparent) 60%, color-mix(in srgb, var(--paper) 60%, transparent)),
    var(--hero-image) center / cover no-repeat,
    var(--paper);
}
.hero h1 { font-size: calc(clamp(34px, 5vw, 64px) * var(--display-scale)); margin: 0 0 var(--sp-16); text-shadow: none; }
.hero h1 span { color: var(--gold-text); }
@media (min-width: 800px) { .hero, .hero.hero--photo { padding-block: var(--sp-96); } }
.hero p { font-size: var(--fs-lede); max-width: 620px; color: var(--cream); }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--sp-12); margin-top: var(--sp-20); }
/* ---------- Cards / grids ---------- */
.grid { display: grid; gap: var(--sp-16); grid-template-columns: repeat(2, 1fr); }
/* A grid still waiting for its titles shows one pulsing block roughly a screen tall, so the content below
   isn't pushed around when the cards arrive. */
[data-page="home"] .grid:empty::before,
#results:empty::before,
#series-list:empty::before {
  content: '';
  grid-column: 1 / -1;
  min-height: 640px;
}
/* The skeleton's look, wherever one waits for content (the app's loading blocks too). */
[data-page="home"] .grid:empty::before,
#results:empty::before,
#series-list:empty::before,
[data-page="app"] .empty.loading {
  border-radius: var(--radius);
  background: var(--raised);
  animation: skeleton-pulse var(--dur-pulse) ease-in-out infinite alternate;
}
#series-list:empty::before { min-height: 700px; }
#results-count { min-height: 1.6em; }
@keyframes skeleton-pulse { from { opacity: .45; } to { opacity: .9; } }
@media (prefers-reduced-motion: reduce) { [data-page="home"] .grid:empty::before, #results:empty::before, #series-list:empty::before, [data-page="app"] .empty.loading { animation: none; } }
@media (min-width: 600px) {
  .grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 800px) {
  .grid { grid-template-columns: repeat(4, 1fr); }
}
/* Desktop: 6 across. Cards are ~175px wide here, so tighten their contents. */
@media (min-width: 1100px) {
  .grid { grid-template-columns: repeat(6, 1fr); gap: var(--sp-14); }
  .grid .card__body { padding: var(--sp-10); gap: var(--sp-4); }
  .grid .card__title { font-size: var(--fs-ui); }
  .grid .card__variant, .grid .card__meta, .grid .foc { font-size: var(--fs-2xs); }
  .grid .card .btn { font-size: var(--fs-sm); padding: var(--sp-8) var(--sp-10); min-height: var(--tap); }
}
.card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 3px solid var(--red);
  border-radius: var(--radius);
  box-shadow: none;
}
.card__body { padding: var(--sp-12); display: flex; flex-direction: column; gap: var(--sp-6); flex: 1; }
.card__title { font: 700 calc(1rem * var(--heading-scale))/1.25 var(--font-body); margin: 0; font-family: var(--font-heading); font-weight: 700; letter-spacing: var(--heading-tracking); }
.card__meta { font-size: var(--fs-sm); margin: 0; color: var(--muted); }
.card__variant { font-size: var(--fs-xs); font-weight: 600; margin: -2px 0 0; }
.show-more { display: flex; margin: var(--sp-24) auto 0; }
.card__foot { margin-top: auto; padding-top: var(--sp-8); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-8); }
.card .btn { width: 100%; }
.card__media { position: relative; }
.card__media .cover { display: block; }
.card__media .cover--placeholder { display: flex; }
/* Series cards: a red bar over the bottom of the cover */
.card__banner { position: absolute; left: 0; right: 0; bottom: 0; padding: var(--sp-10) var(--sp-8); background: var(--red-btn); color: var(--on-primary); font: 700 var(--fs-xs)/1 var(--font-body); letter-spacing: .12em; text-align: center; text-transform: uppercase; }
/* Collector chips (1st Appearance, Key Issue, …) */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-4); list-style: none; margin: 0; padding: 0; }
.chips li {
  font-size: var(--fs-2xs);
  font-weight: 700;
  line-height: 1;
  padding: var(--sp-4) var(--sp-8);
  background: var(--raised);
  color: var(--gold-text);
  border: 1px solid var(--line);
  border-radius: var(--radius-xs);
}
.pick-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-4);
  font-size: var(--fs-2xs);
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  padding: var(--sp-6) var(--sp-8);
  background: var(--gold);
  color: var(--on-accent);
  border-radius: var(--radius-xs);
  box-shadow: none;
  letter-spacing: .06em;
  text-transform: uppercase;
}
/* "Top 10" (most reserved) badge: a white circle on the cover's top-right corner; a Staff Pick tag moves to the left. */
.top-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: var(--z-raised);
  display: grid;
  place-content: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: #fff;
  color: var(--brand-primary);
  box-shadow: var(--shadow-badge);
  text-align: center;
  line-height: .9;
  font-weight: 800;
}
.top-badge__top { font-size: var(--fs-3xs); letter-spacing: .08em; text-transform: uppercase; }
.top-badge__num { font-size: var(--fs-num); }
.has-top-badge .pick-badge { right: auto; left: 8px; }
@media (min-width: 1100px) {
  .grid .top-badge { top: 6px; right: 6px; width: 40px; height: 40px; }
  .grid .top-badge__num { font-size: var(--fs-num-sm); }
  .grid .has-top-badge .pick-badge { right: auto; left: 6px; }
  .grid .pick-badge { top: 6px; right: 6px; font-size: var(--fs-2xs); padding: var(--sp-4) var(--sp-6); }
}
.cover { width: 100%; aspect-ratio: 6.625 / 10.25; background: var(--raised); object-fit: contain; }
.cover--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-12);
  text-align: center;
  font-weight: 700;
  line-height: 1.2;
  background: radial-gradient(#ffffff0c 1px, transparent 1px) 0 0 / 7px 7px, var(--raised);
  color: var(--muted);
  font-size: var(--fs-base);
}
/* ---------- Status badges (icon + text, never color alone) ---------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-4);
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  border-radius: var(--radius-xs);
  background: var(--teal);
  color: var(--paper);
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: var(--fs-2xs);
  padding: var(--sp-4) var(--sp-8);
}
.badge--available { background: var(--ok); }
.badge--just_arrived, .badge--new_this_wednesday { background: var(--gold); color: var(--on-accent); }
.badge--sold_out { background: var(--sold-out); color: var(--on-sold-out); }
.badge--backorder { background: var(--cream); }
.badge--pre_order, .badge--coming_soon { background: var(--teal); }
.badge--low_stock { background: var(--warn); }
.badge--sale { background: var(--red-btn); color: var(--on-primary); }
.badge--clearance { background: var(--clearance); }
.foc { font-size: var(--fs-xs); font-weight: 700; }
.foc--soon { color: var(--error); }
/* ---------- Filters ---------- */
/* Checkbox dropdown (multi-select filter) — the button matches a <select>. */
.multi { position: relative; }
.multi__button {
  display: flex;
  align-items: center;
  width: 100%;
  height: var(--field-h);
  padding: 0 var(--sp-32) 0 var(--sp-12);
  font: inherit;
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
  background: var(--surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23444' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 12px center;
  border: 1px solid var(--field-line);
  background-color: var(--paper);
  color: var(--ink);
  border-radius: var(--radius-field);
}
.multi__button:hover { border-color: var(--ink); }
.multi__button[aria-expanded='true'] { border-color: var(--ink); }
.multi__summary { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.multi__panel {
  position: absolute;
  z-index: var(--z-popover);
  top: calc(100% + 4px);
  left: 0;
  width: max(100%, min(300px, calc(100vw - 2 * var(--gutter))));
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--sp-8);
  background: var(--raised);
  border: 1px solid var(--line);
}
.multi__search { margin-bottom: var(--sp-6); }
.multi__options { border: 0; margin: 0; padding: 0; max-height: 280px; overflow-y: auto; }
.multi__option {
  display: flex; align-items: center; gap: var(--sp-10); min-height: var(--tap); padding: var(--sp-6) var(--sp-8);
  font-weight: 400; margin: 0; border-radius: var(--radius-sm); cursor: pointer;
}
.multi__option:hover { background: var(--surface); }
.multi__option[hidden] { display: none; }
.multi__divider { border: 0; border-top: var(--border); margin: var(--sp-6) var(--sp-8); }
.multi__actions { display: flex; justify-content: space-between; gap: var(--sp-8); padding-top: var(--sp-8); margin-top: var(--sp-6); border-top: var(--border); }
.multi__actions button {
  font: inherit;
  font-weight: 700;
  min-height: var(--tap);
  padding: 0 var(--sp-14);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
  background: none;
  color: var(--ink);
}
.multi__actions .multi__clear { text-decoration: underline; text-underline-offset: 3px; }
.multi__actions .multi__done { background: var(--gold); color: var(--on-accent); }
.filters {
  display: grid; gap: var(--sp-12); grid-template-columns: 1fr 1fr;
  background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: var(--sp-14); margin-bottom: var(--sp-20);
}
.filters .field { margin: 0; }
.filters .field--search { grid-column: 1 / -1; }
.filters label:not(.multi__option), .filters .label { font-size: var(--fs-sm); }
@media (min-width: 800px) {
  /* One row however many filters a page has (Pre-Orders has five). */
  .filters { display: flex; align-items: end; }
  .filters .field { flex: 1 1 0; min-width: 0; }
  .filters .field--search { flex-grow: 1.6; }
}
.results-count { color: var(--muted); font-size: var(--fs-ui); margin-bottom: var(--sp-12); }
.empty { padding: var(--sp-32); text-align: center; border: 2px dashed var(--line); border-radius: var(--radius); color: var(--muted); }
/* ---------- Dialogs (reservation form, lightbox) ---------- */
dialog {
  box-shadow: var(--shadow-lg);
  padding: 0;
  width: min(520px, calc(100vw - 2 * var(--gutter)));
  max-height: calc(100vh - 32px);
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}
dialog::backdrop { background: #000c; }
/* While a dialog or the lightbox is open the page behind it stays put: it can't scroll (the scrollbar's space is kept, so
   nothing shifts), and scrolling to the end of a long dialog (or the title dialog's scrolling body) doesn't carry on into
   the page. */
html:has(dialog:modal) { overflow: hidden; scrollbar-gutter: stable; }
dialog, dialog .dialog__body { overscroll-behavior: contain; }
.dialog__head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--sp-12); padding: var(--sp-16) var(--sp-16) 0; }
.dialog__head h2 { font-size: var(--fs-title); margin: 0; }
.dialog__body { padding: var(--sp-16); }
.dialog__close {
  display: grid;
  place-items: center;
  flex: none;
  background: none;
  border: 1px solid var(--field-line);
  border-radius: 50%;
  font-size: var(--fs-lede);
  line-height: 1;
  cursor: pointer;
  width: var(--tap);
  height: var(--tap);
  margin: 0;
  color: var(--ink);
}
.dialog__close:hover { background: var(--raised); border-color: var(--teal); }
/* Keyboard focus is the blue as the button's background, not an outline (an outline gets clipped at the dialog's edge). */
.dialog__close:focus-visible { outline: none; background: var(--teal); border-color: var(--teal); color: var(--paper); }
/* High-contrast / forced-colors modes drop background colors, so give the focused button a real outline there. */
@media (forced-colors: active) { .dialog__close:focus-visible { outline: 3px solid Highlight; outline-offset: -3px; } }
.honeypot { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.confirm { text-align: center; padding: var(--sp-8) 0; }
.confirm__big { font-family: var(--font-display); font-weight: var(--display-weight); font-size: calc(1.6rem * var(--display-scale)); margin-bottom: var(--sp-8); color: var(--gold-text); }
.notice {
  padding: var(--sp-10) var(--sp-12);
  background: var(--teal-dark);
  border: 0;
  border-left: 3px solid var(--teal);
  border-radius: 0;
  font-weight: 400;
  color: var(--ink);
}
/* Fits the picture: a dialog's width: auto would stretch it across the page. */
.lightbox { width: fit-content; max-width: calc(100vw - 32px); background: #000; }
.lightbox img { display: block; max-height: calc(100vh - 64px); width: auto; }
.lightbox__close { position: absolute; top: 8px; right: 8px; width: var(--tap); height: var(--tap); border-radius: 50%; border: 2px solid #fff; background: #000; color: #fff; font-size: var(--fs-lede); cursor: pointer; }
/* ---------- Title details dialog (click a cover) ---------- */
.card__open { display: block; width: 100%; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; }
.card__open:hover .cover { filter: brightness(1.08); }
.card__title-open { display: inline; padding: 0; border: 0; background: none; color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; text-align: left; cursor: pointer; }
.card__title-open:hover { text-decoration: underline; text-underline-offset: 3px; }
/* A title is one line of text; its tap area reaches past it to 44px tall, without moving anything. */
.card__title { position: relative; }
.card__title-open::after { content: ""; position: absolute; inset: -13px 0; }
.title-modal { width: min(900px, calc(100vw - 2 * var(--gutter))); max-height: calc(100vh - 32px); overflow: hidden; }
.title-modal__head { justify-content: flex-end; padding: var(--sp-8) var(--sp-8) 0; }
.title-modal .dialog__body { overflow-y: auto; max-height: calc(100vh - 100px); padding: 0 var(--sp-24) var(--sp-24); }
.title-modal__layout { display: grid; gap: var(--sp-20); }
.title-modal__media .cover { max-width: 240px; margin-inline: auto; border-radius: var(--radius); }
.title-modal__cover { position: relative; max-width: 240px; margin-inline: auto; }
.title-modal__cover .top-badge { top: 8px; right: 8px; }
.title-modal__zoom { display: block; cursor: zoom-in; }
.title-modal__zoom:hover .cover { filter: brightness(1.08); }
.title-modal__covers { list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-6); justify-content: center; padding: 0; margin: var(--sp-12) 0 var(--sp-4); }
.title-modal__thumb { display: block; width: 52px; aspect-ratio: 6.625 / 10.25; padding: 0; background: var(--raised); border: 2px solid var(--line); border-radius: var(--radius-sm); cursor: pointer; overflow: hidden; color: var(--muted); }
.title-modal__thumb img { width: 100%; height: 100%; object-fit: cover; }
.title-modal__thumb.is-on { border-color: var(--gold-text); }
.title-modal__thumb:hover { border-color: var(--teal); }
.title-modal__nocover { display: grid; place-items: center; height: 100%; }
.title-modal__media > .card__meta { text-align: center; }
.title-modal__title { font-size: clamp(1.5rem, 4vw, 2.1rem); margin: var(--sp-8) 0 var(--sp-4); text-transform: uppercase; letter-spacing: -.02em; line-height: 1; }
.title-modal__when { margin: 0 0 var(--sp-8); }
.title-modal__alert { margin: var(--sp-12) 0; }
.title-modal__alert .card__meta:empty { display: none; }
.title-modal__cal { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--sp-12); margin: 0 0 var(--sp-8); font-size: var(--fs-sm); }
.title-modal__cal span { color: var(--muted); }
.title-modal__cal a { display: inline-flex; align-items: center; min-height: var(--tap); font-weight: 700; }
.title-modal__share { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-12); margin: var(--sp-16) 0 0; }
.title-modal__shared:empty { display: none; }
.title-modal__desc { margin: var(--sp-16) 0 var(--sp-12); font-size: var(--fs-base); line-height: 1.55; }
.title-modal .card__foot { margin: var(--sp-12) 0 var(--sp-4); }
@media (min-width: 700px) { .title-modal__layout { grid-template-columns: 260px minmax(0, 1fr); gap: var(--sp-24); } .title-modal__media .cover, .title-modal__cover { max-width: none; } }
/* Phones: the whole screen (100dvh, so iPhone's browser bars and the app's status bar don't push it off), the close
   button below the status bar and always in view, and only the body scrolls. */
@media (max-width: 599px) {
  .title-modal { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; margin: 0; border: 0; border-radius: 0; }
  .title-modal[open] { display: flex; flex-direction: column; }
  .title-modal__head { flex: none; padding: calc(var(--sp-8) + env(safe-area-inset-top)) calc(var(--sp-8) + env(safe-area-inset-right)) var(--sp-4) var(--sp-8); }
  .title-modal .dialog__body { flex: 1 1 auto; min-height: 0; max-height: none; overscroll-behavior: none; padding: 0 var(--sp-16) calc(var(--sp-24) + env(safe-area-inset-bottom)); }
  /* A sheet: it slides up to open and down to close, and follows a finger swiping it down from the top of its content
     (js/title-modal.js sets --sheet-drag and the classes). No overscroll bounce, so the swipe starts at once. */
  .title-modal { transform: translateY(var(--sheet-drag, 0px)); transition: transform var(--dur-sheet) var(--ease-sheet); }
  .title-modal[open] { animation: sheet-up var(--dur-sheet) var(--ease-sheet); }
  .title-modal.is-dragging { transition: none; }
  .title-modal.is-closing { transform: translateY(100%); transition-timing-function: ease-in; }
  .title-modal::backdrop { transition: opacity var(--dur-sheet); }
  .title-modal.is-closing::backdrop { opacity: 0; }
}
@keyframes sheet-up { from { transform: translateY(100%); } }
@media (prefers-reduced-motion: reduce) { .title-modal[open] { animation: none; } }
/* ---------- Reservation list ---------- */
.list-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--z-bar);
  padding: var(--sp-10) 0 calc(10px + env(safe-area-inset-bottom));
  background: var(--surface);
  border-top: 1px solid var(--line);
  box-shadow: none;
}
.list-bar__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); }
.list-bar__text { margin: 0; font-size: var(--fs-md); line-height: 1.3; }
.list-bar .btn { flex: none; }
body.has-list-bar { padding-bottom: var(--list-bar-h); }
/* ---------- Live chat (js/chat.js) ---------- */
.chat-launch, .chat { position: fixed; right: var(--sp-16); bottom: var(--sp-16); z-index: var(--z-chat); }
body.has-list-bar .chat-launch, body.has-list-bar .chat { bottom: calc(var(--list-bar-h) + var(--sp-16)); }
body.has-list-bar .chat { max-height: min(600px, calc(100dvh - var(--list-bar-h) - var(--sp-32))); }
/* In the shop's app the button and box sit above the tab bar (and the phone's home-bar inset). */
body[data-page="app"] .chat-launch, body[data-page="app"] .chat { bottom: calc(var(--tab-bar-h) + env(safe-area-inset-bottom) + var(--sp-16)); }
body[data-page="app"] .chat { max-height: min(600px, calc(100dvh - var(--tab-bar-h) - env(safe-area-inset-bottom) - var(--sp-32))); }
body.app-locked .chat-launch { bottom: var(--sp-16); } /* the sign-in screen has no tab bar */
/* The button is a round comic word balloon (an oval with a pointed tail at the lower left, and three dots cut out of it) in the shop's main color; its drawing takes the text color
   on that fill. The dot for a new reply sits on the rim in a ring of the page color so it reads on any page. */
.chat-launch { display: grid; place-items: center; width: calc(var(--sp-40) + var(--sp-16)); height: calc(var(--sp-40) + var(--sp-16)); min-height: 0; padding: 0; border-radius: 50%; box-shadow: var(--shadow-lg); }
.chat-launch__icon { width: calc(var(--sp-24) + var(--sp-12)); height: auto; fill: currentColor; }
.chat-launch__dot { position: absolute; top: var(--sp-2); right: var(--sp-2); width: var(--sp-14); height: var(--sp-14); border: 2px solid var(--paper); border-radius: 50%; background: var(--gold-text); }
.chat { display: flex; flex-direction: column; width: min(380px, calc(100vw - 2 * var(--sp-16))); max-height: min(600px, calc(100dvh - var(--sp-32))); background: var(--surface); border: var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.chat[hidden] { display: none; }
.chat__head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); padding: var(--sp-8) var(--sp-12) var(--sp-8) var(--sp-14); border-bottom: var(--border); }
.chat__title { margin: 0; font-size: var(--fs-compact); }
.chat__body { display: flex; flex: 1; flex-direction: column; min-height: 0; }
.chat__form { padding: var(--sp-12) var(--sp-14); overflow-y: auto; }
.chat__note { margin: 0 0 var(--sp-12); font-size: var(--fs-sm); color: var(--muted); }
.chat__log { display: flex; flex: 1; flex-direction: column; gap: var(--sp-8); min-height: calc(var(--sp-64) * 3); padding: var(--sp-12) var(--sp-14); overflow-y: auto; }
.chat__msg { max-width: 85%; padding: var(--sp-8) var(--sp-12); border-radius: var(--radius-field); background: var(--raised); overflow-wrap: anywhere; }
.chat__msg p { margin: 0; font-size: var(--fs-md); white-space: pre-wrap; }
.chat__msg--mine { align-self: flex-end; background: var(--red-btn); color: var(--on-primary); }
.chat__time { display: block; margin-top: var(--sp-4); font-size: var(--fs-2xs); }
.chat__body > .chat__note { padding: 0 var(--sp-14); }
.chat__send { display: flex; align-items: flex-end; gap: var(--sp-8); padding: var(--sp-10) var(--sp-14); border-top: var(--border); }
.chat__send textarea { flex: 1; min-width: 0; }
.chat__foot { display: flex; flex-wrap: wrap; align-items: center; column-gap: var(--sp-12); margin: 0; padding: 0 var(--sp-14); border-top: var(--border); font-size: var(--fs-xs); color: var(--muted); }
.chat__hide { min-height: var(--tap); padding: 0; font: inherit; color: var(--teal); text-decoration: underline; background: none; border: 0; cursor: pointer; }
.chat__hide:hover { color: var(--teal-hover); }
.chat__body > .form-error { margin: 0; padding: 0 var(--sp-14) var(--sp-10); }
@media (max-width: 479px) {
  .chat { left: 0; right: 0; bottom: 0; width: auto; max-height: 85dvh; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
  body.has-list-bar .chat { bottom: 0; max-height: 85dvh; }
  body[data-page="app"] .chat { bottom: 0; max-height: 85dvh; padding-bottom: env(safe-area-inset-bottom); } /* a sheet over the tab bar */
}
.list-dialog { width: min(600px, calc(100vw - 2 * var(--gutter))); }
.list-dialog__sub { font-size: var(--fs-sub); margin-top: var(--sp-20); }
.list-dialog__names { display: grid; grid-template-columns: minmax(0, 1fr); column-gap: var(--sp-12); }
@media (min-width: 480px) { .list-dialog__names { grid-template-columns: 1fr 1fr; } }
.list-lines { list-style: none; margin: 0 0 var(--sp-8); padding: 0; }
.list-line {
  display: grid; grid-template-columns: 52px 1fr; gap: var(--sp-4) var(--sp-12); align-items: start;
  padding: var(--sp-12) 0; border-bottom: var(--border);
}
.list-line .cover { width: 52px; border-radius: var(--radius-sm); padding: var(--sp-4); }
/* The cover and title open the title's details; the title's tap area stretches as on a card (.card__title-open). */
.list-line__open { grid-row: span 2; display: block; padding: 0; border: 0; background: none; cursor: pointer; }
.list-line__open:hover .cover { filter: brightness(1.08); }
.list-line__title { position: relative; }
.list-line .cover--placeholder { font-size: var(--fs-3xs); padding: var(--sp-4); }
.list-line__info { display: flex; flex-direction: column; gap: var(--sp-2); min-width: 0; }
.list-line__info .foc { margin: var(--sp-2) 0 0; }
.list-line__controls { display: flex; align-items: center; gap: var(--sp-12); }
.list-line__qty { width: 72px; }
.list-line__remove { background: none; border: 0; padding: var(--sp-8) var(--sp-4); min-height: var(--tap); font: inherit; font-size: var(--fs-ui); text-decoration: underline; text-underline-offset: 3px; color: var(--muted); cursor: pointer; }
.list-line__remove:hover { color: var(--gold-text); }
@media (min-width: 600px) {
  .list-line { grid-template-columns: 52px 1fr auto; align-items: center; }
  .list-line__open { grid-row: auto; }
}
.confirm__lines { text-align: left; display: inline-block; margin: 0 0 1em; padding-left: 1.2em; }
/* ---------- Calendar ---------- */
.event { display: grid; grid-template-columns: 64px minmax(0, 1fr); gap: var(--sp-14); align-items: start; }
.event + .event { margin-top: var(--sp-16); }
.event__date { text-align: center; background: var(--surface); box-shadow: var(--shadow); border-radius: var(--radius); overflow: hidden; }
.event__month {
  display: block;
  font-size: var(--fs-2xs);
  font-weight: 700;
  text-transform: uppercase;
  padding: var(--sp-2) 0;
  background: var(--red-btn);
  color: var(--on-primary);
}
.event__day { display: block; font-family: var(--font-display); font-weight: var(--display-weight); font-size: calc(1.6rem * var(--display-scale)); padding: var(--sp-4) 0; }
.event__type { font-size: var(--fs-2xs); font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--gold-text); }
.event h3 { margin: var(--sp-2) 0 var(--sp-4); }
.event__when { color: var(--muted); font-size: var(--fs-ui); margin-bottom: var(--sp-6); }
.event__summary { margin: 0 0 var(--sp-6); }
.event__more { margin: 0 0 var(--sp-10); font-weight: 700; }
.event__actions { display: flex; flex-wrap: wrap; gap: var(--sp-6) var(--sp-14); font-size: var(--fs-ui); }
.event__img { margin: var(--sp-8) 0; border-radius: var(--radius); max-width: min(360px, 100%); height: auto; }
/* Event page: the photo sits at the top, with space below it. */
#event .event__img { margin: var(--sp-8) auto var(--sp-24); max-width: min(100%, 560px); }
/* Calendar page: the photo sits to the right of the text on wider screens and is left off phones (it's on the event's page). */
.event__body { display: grid; gap: var(--sp-10); }
.event__photo { display: none; }
.event__body .event__img { margin: 0; max-width: 100%; width: 100%; }
@media (min-width: 700px) {
  .event__body--img { grid-template-columns: minmax(0, 1fr) clamp(220px, 34%, 340px); gap: var(--sp-24); align-items: start; }
  .event__photo { display: block; }
}
/* Smaller version for the home page's "Coming up" list */
.event--compact { grid-template-columns: 48px minmax(0, 1fr); gap: var(--sp-12); }
.event--compact + .event--compact { margin-top: var(--sp-12); }
.event--compact .event__month { font-size: var(--fs-2xs); padding: var(--sp-2) 0; }
.event--compact .event__day { font-size: var(--fs-num-sm); padding: var(--sp-2) 0; }
.event--compact .event__type { font-size: var(--fs-2xs); }
.event--compact h3 { font-size: var(--fs-compact); margin: var(--sp-2) 0 var(--sp-2); }
.event--compact h3 a { color: inherit; text-decoration: none; }
.event--compact h3 a:hover { text-decoration: underline; }
.event--compact .event__when { font-size: var(--fs-sm); margin-bottom: 0; }
.event--compact:last-child { margin-bottom: var(--sp-16); }
.month-heading { font-size: var(--fs-title); padding-bottom: var(--sp-6); border-bottom: var(--border); margin: var(--sp-32) 0 var(--sp-16); }
.month-heading:first-child { margin-top: 0; }
/* ---------- Misc blocks ---------- */
.info-grid { display: grid; gap: var(--sp-20); }
@media (min-width: 800px) {
  .info-grid { grid-template-columns: 1fr 1fr; }
  .info-grid--single { grid-template-columns: minmax(0, 640px); }
}
.sell-cols { align-items: start; gap: var(--sp-32); }
.sell-cols > * > :first-child { margin-top: 0; }
@media (min-width: 800px) { .sell-cols { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); } }
.panel { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); padding: var(--sp-24); }
.panel h2 { font-size: var(--fs-title); }
/* A rounded note on a light tint of the accent color, dark text. */
.callout { background: color-mix(in srgb, var(--gold) 45%, #fff); color: #161616; border-radius: var(--radius); padding: var(--sp-16) var(--sp-20); margin: 0; }
.callout a { color: #161616; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.callout a:hover { text-decoration-thickness: 2px; }
.map { display: block; width: 100%; aspect-ratio: 4 / 3; border: 0; border-radius: var(--radius); background: var(--raised); box-shadow: none; }
.map--small { max-width: 480px; aspect-ratio: 16 / 10; margin: 1em 0; }
/* Visit page: fills the right-hand column, at least as tall as the contact details. */
#map { display: flex; flex-direction: column; }
.map--large { flex: 1; min-height: 360px; aspect-ratio: auto; }
@media (min-width: 800px) {
  .map--large { min-height: 480px; }
}
.signup { display: flex; flex-direction: column; gap: var(--sp-10); max-width: 480px; }
@media (min-width: 600px) {
  .signup { flex-direction: row; }
  .signup input { flex: 1; }
}
details { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); margin-bottom: var(--sp-10); }
summary { cursor: pointer; font-weight: 700; padding: var(--sp-14) var(--sp-16); min-height: var(--tap); list-style: none; display: flex; align-items: center; gap: var(--sp-10); }
summary::-webkit-details-marker { display: none; }
/* One indicator for every show/hide box: a chevron that points down when the box is closed and flips to ^ when it's open. */
summary::after {
  content: ''; flex: none; width: .5em; height: .5em; margin-left: auto; margin-top: -.25em;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); transition: transform var(--dur);
}
details[open] > summary::after { transform: rotate(225deg); margin-top: .25em; }
@media (prefers-reduced-motion: reduce) {
  summary::after { transition: none; }
  html { scroll-behavior: auto; }
}
details > div { padding: 0 var(--sp-16) var(--sp-14); }
.search-hits { list-style: none; padding: 0; margin: 0 0 var(--sp-8); display: grid; gap: var(--sp-12); }
.search-hits li { padding: var(--sp-10) var(--sp-14); background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow); }
.search-hits p { margin: var(--sp-4) 0 0; }
.search-hits mark { padding: 0 var(--sp-2); border-radius: var(--radius-xs); background: var(--gold); color: var(--on-accent); }
#pages, #faq, #events, #news { margin-top: var(--sp-32); }
#series { margin-bottom: var(--sp-24); }
.post-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-16); }
.post-list time { font-size: var(--fs-sm); color: var(--muted); }
.post-list__title { font-size: var(--fs-title); margin: var(--sp-4) 0 var(--sp-8); }
/* Title links read as titles; the underline appears on hover (same as event and news titles elsewhere). */
.post-list__title a, .event h3 a, .home-news h3 a { text-decoration: none; }
.post-list__title a:hover, .event h3 a:hover { text-decoration: underline; }
.post-list p { margin: 0; }
.home-news { margin-top: var(--sp-32); }
.home-news .post-list { gap: var(--sp-12); margin-bottom: var(--sp-12); }
.home-news h3 { font-size: var(--fs-compact); margin: var(--sp-2) 0 var(--sp-2); }
.home-news h3 a { color: inherit; text-decoration: none; }
.home-news h3 a:hover { text-decoration: underline; }
.home-news .post-list p { margin: 0; font-size: var(--fs-ui); color: var(--muted); }
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}
.newsletter { padding-block: var(--sp-40); text-align: center; background: var(--surface); border-top: 1px solid var(--line); }
.newsletter .lede { margin-inline: auto; }
.newsletter #newsletter-form { display: flex; justify-content: center; }
/* Free-form staff text on the homepage; hidden when empty. */
.home-text { padding-block: var(--sp-24) 0; }
/* Staff text that arrives after the page: hold its usual height until it does, so the sections below don't jump
   (the script hides a block that turns out to be empty). */
[data-content="home-top:body"]:empty { min-height: 700px; }
[data-content="home-preorders:lede"]:empty { min-height: 130px; }
@media (min-width: 800px) {
  [data-content="home-top:body"]:empty { min-height: 390px; }
  [data-content="home-preorders:lede"]:empty { min-height: 55px; }
}
.home-text > :last-child { margin-bottom: 0; }
/* ---------- Customer account ---------- */
.account-panel { max-width: 460px; }
.account-who { margin: 0 0 var(--sp-16); }
.link-button { background: none; border: 0; padding: 0; font: inherit; color: var(--teal); text-decoration-line: underline; cursor: pointer; }
.account-grid { display: grid; gap: var(--sp-20); }
@media (min-width: 800px) {
  .account-grid { grid-template-columns: 3fr 2fr; align-items: start; }
}
.account-fieldset { border: 0; padding: 0; margin: 0 0 var(--sp-14); }
.account-fieldset legend { font-weight: 700; padding: 0; }
.account-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-12); }
.field--check { display: flex; align-items: center; gap: var(--sp-10); min-height: var(--tap); }
.field--check label { margin: 0; font-weight: 400; }
/* Survey: a question with more than 6 choices lists them in two columns once there is room. */
.survey-choice-other, .survey-choices--cols .field--check { break-inside: avoid; }
.survey-q { border: 0; padding: 0; margin: 0 0 var(--sp-24); }
.survey-other { margin: 0 0 var(--sp-8) calc(var(--sp-24) + var(--sp-10)); }   /* lines up with the "Other" label */
.survey-rating { display: flex; flex-wrap: wrap; gap: var(--sp-20); }
.prose hr.survey-break { margin: 1.2em 0 1.8em; }
.survey-progress { height: var(--sp-8); margin-bottom: 1.5em; overflow: hidden; border-radius: var(--radius-pill); background: var(--line); }
.survey-progress__bar { width: 0; height: 100%; background: var(--teal); transition: width var(--dur); }
.post__cover { margin-bottom: 1em; }
@media (min-width: 600px) { .survey-choices--cols { column-count: 2; column-gap: var(--sp-32); } }
.account-saved { color: var(--ok); font-weight: 700; margin: 0 0 var(--sp-8); }
.account-deleted { margin: 0 0 var(--sp-16); } /* over the sign-in form, once, after deleting the account */
.account-lines { list-style: none; margin: 0; padding: 0; }
.account-line { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-12); padding: var(--sp-10) 0; border-bottom: 1px solid var(--line); }
.account-line .card__meta { display: block; }
.account-line__status { flex: none; font-size: var(--fs-sm); font-weight: 700; text-align: right; }
.account-line__status--arrived { color: var(--ok); }
.account-line__status--not_ordered { color: var(--gold-text); }
.account-past { margin-top: var(--sp-16); }
/* My Pull List → Export my comics */
.account-export__actions { display: flex; flex-wrap: wrap; gap: var(--sp-12); }
.account-export__how { margin: var(--sp-12) 0 0; padding-left: var(--sp-20); font-size: var(--fs-sm); color: var(--muted); }
.account-export__how li + li { margin-top: var(--sp-6); }
.account-group { font-size: var(--fs-sub); margin: var(--sp-20) 0 var(--sp-4); padding-bottom: var(--sp-6); border-bottom: var(--border); }
.account-group:empty { display: none; }
.account-line .cover { width: 56px; height: auto; flex: none; border-radius: var(--radius-sm); }
.account-line__info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-2); }
.account-line__info .card__variant { margin: 0; }
.account-line__qty { flex: none; font-size: var(--fs-ui); }
/* Titles a follow added since the last visit */
.new-badge { align-self: flex-start; display: inline-block; padding: var(--sp-2) var(--sp-8); border-radius: var(--radius-pill); background: var(--gold); color: var(--on-accent); font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .02em; text-transform: uppercase; }
.account-line--new { box-shadow: inset 4px 0 0 var(--gold); padding-left: var(--sp-12); background: color-mix(in srgb, var(--gold) 8%, transparent); }
.account-new .new-badge { margin-right: var(--sp-6); vertical-align: 1px; }
.account-summary { background: var(--raised); border-radius: var(--radius); padding: var(--sp-14) var(--sp-16); margin: 0 0 var(--sp-8); }
.account-summary p { margin: 0 0 var(--sp-8); }
.account-summary__totals { margin: 0 0 var(--sp-6); }
.account-summary__totals div { display: flex; justify-content: space-between; gap: var(--sp-12); padding: var(--sp-2) 0; }
.account-summary__totals dt, .account-summary__totals dd { margin: 0; }
.account-summary__total { border-top: var(--border); margin-top: var(--sp-4); padding-top: var(--sp-6) !important; font-weight: 700; }
.account-summary--fold { padding: 0; border: 0; box-shadow: none; }
.account-summary--fold > summary { gap: var(--sp-12); padding: var(--sp-12) var(--sp-16); }
.account-summary__amount { margin-left: auto; }
.account-summary--fold > summary::after { margin-left: 0; }
.account-summary--fold > div { padding: 0 var(--sp-16) var(--sp-12); }
/* The app's Following fold at the top of My List: what they follow, counted on one line until it's opened. */
.app-follows { background: var(--raised); border: 0; border-radius: var(--radius); margin: 0 0 var(--sp-16); }
.app-follows > summary { gap: var(--sp-12); padding: var(--sp-12) var(--sp-16); }
.app-follows__count { margin-left: auto; color: var(--muted); font-size: var(--fs-ui); font-weight: 400; }
.app-follows > summary::after { margin-left: 0; }
.app-follows > div { padding: 0 var(--sp-16) var(--sp-12); }
.account-move { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); flex-wrap: wrap; }
/* ---------- Follow (signed-in cards): a link on the card, choices in a dialog ---------- */
.follow-open { display: block; width: 100%; margin-top: var(--sp-6); padding: var(--sp-8) 0; min-height: var(--tap); background: none; border: 0; font: inherit; font-size: var(--fs-ui); font-weight: 700; text-align: left; color: var(--teal); cursor: pointer; }
.follow-open:hover { text-decoration: underline; }
.follow-open--on { color: var(--muted); }
.follow-open--on:hover { text-decoration: none; }
a.follow-open { box-sizing: border-box; line-height: 24px; }
@media (max-width: 599px) {
  .follow-open__more { display: none; }
}
.follow-dialog { width: min(560px, calc(100vw - 2 * var(--gutter))); }
.follow-dialog .dialog__body { overflow-y: auto; max-height: calc(100vh - 110px); }
.follow-dialog__for { margin: 0 0 var(--sp-8); font-weight: 700; color: var(--ink); }
.follow-dialog__intro { margin: 0 0 var(--sp-14); font-size: var(--fs-md); color: var(--muted); }
.follow-group { margin: 0 0 var(--sp-16); }
.follow-group h3 { font-size: var(--fs-sub); padding-bottom: var(--sp-6); border-bottom: var(--border); margin: 0 0 var(--sp-10); }
.follow-person { margin: 0 0 var(--sp-14); }
.follow-person__tag {
  font-size: var(--fs-2xs);
  font-weight: 700;
  padding: var(--sp-2) var(--sp-8);
  border-radius: var(--radius-pill);
  white-space: nowrap;
  background: var(--gold);
  color: var(--on-accent);
}
.follow-choices { display: grid; gap: var(--sp-8); margin-top: var(--sp-6); grid-template-columns: 1fr; }
@media (min-width: 480px) {
  .follow-choices { grid-template-columns: 1fr 1fr; }
}
.follow-choice {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-2);
  text-align: left;
  padding: var(--sp-10) var(--sp-12);
  min-height: 52px;
  font: inherit;
  border-radius: var(--radius);
  border: 1px solid var(--field-line);
  cursor: pointer;
  background: var(--paper);
  color: var(--ink);
}
.follow-choice:hover { border-color: var(--teal); }
.follow-choice.is-on { background: var(--gold); color: var(--on-accent); border-color: var(--gold); }
.follow-choice__label { font-weight: 700; font-size: var(--fs-md); }
.follow-choice__hint { font-size: var(--fs-xs); color: var(--muted); }
.follow-choice.is-on .follow-choice__hint { color: var(--on-accent); }
.follow-choice:disabled { opacity: .6; cursor: progress; }
.follow-dialog__status { min-height: 1.4em; margin: var(--sp-4) 0 var(--sp-12); font-weight: 700; color: var(--ok); }
.follow-dialog__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-12);
  flex-wrap: wrap;
  position: sticky;
  bottom: -16px;
  margin: 0 -16px -16px;
  padding: var(--sp-12) var(--sp-16);
  border-top: var(--border);
  background: var(--surface);
}
.follow-form { display: grid; gap: var(--sp-8); margin-bottom: var(--sp-14); }
.follow-form__row { display: flex; gap: var(--sp-8); flex-wrap: wrap; }
.follow-form__row input { flex: 1 1 200px; }
.follow-results { list-style: none; margin: 0; padding: 0; }
.follow-results__head { margin: var(--sp-14) 0 var(--sp-2); font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.follow-results li { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-8); flex-wrap: wrap; padding: var(--sp-8) 0; border-bottom: 1px solid var(--line); }
.follow-results__act { display: flex; gap: var(--sp-6); flex-wrap: wrap; }
/* On a phone the actions always sit on their own line under the name, so every row lines up the same. */
@media (max-width: 599px) {
  .follow-results li { flex-direction: column; align-items: flex-start; }
}
.follow-results .is-on { cursor: default; opacity: .8; }
#artists { margin-bottom: var(--sp-24); }
.follow-subs { list-style: none; margin: 0 0 var(--sp-12); padding: 0; }
.follow-subs li { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-10); padding: var(--sp-8) 0; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.account-col { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-20); min-width: 0; }
/* Following, My Profile and Delete my account fold away under their titles (the panel's padding moves inside). */
.account-fold { padding: 0; margin: 0; }
.account-fold > summary { padding: var(--sp-16) var(--sp-24); }
.account-fold > summary h2 { margin: 0; }
.account-fold > div { padding: 0 var(--sp-24) var(--sp-24); }
.account-lastupdate { margin: -4px 0 var(--sp-10); }
/* ---------- Pre-orders: collapsible "How it works" ---------- */
.how-it-works { box-shadow: none; margin: 0 0 var(--space-block); background: none; border: 0; }
.how-it-works summary { display: inline-flex; padding: var(--sp-8) 0; min-height: var(--tap); color: var(--teal); font-weight: 700; }
.how-it-works summary::after { margin-left: var(--sp-2); }
.how-it-works > div { padding: 0; }
.how-it-works .page-body { margin-bottom: 0; }
.follow-item { display: flex; align-items: center; gap: var(--sp-10); }
.follow-allcovers { display: inline-flex; align-items: center; gap: var(--sp-6); margin: 0; font-weight: 400; font-size: var(--fs-ui); white-space: nowrap; cursor: pointer; }
.follow-thumb { width: 36px; height: 54px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--line); flex: none; }
/* Bronze Age Modern + Dusty Blue — the public-site theme, applied over the rules above.
   Dark page, brick-red buttons, gold accents, dusty-blue links and focus.
   The colors staff pick in Shop Settings are overridden here (!important beats the inline
   values site.js sets), so the whole site keeps one palette. */
/* ---------- Top bar (announcement + search) ---------- */
.topbar__search input::placeholder { color: var(--muted); opacity: 1; }
/* ---------- Header / nav ---------- */
.brand__name span { color: var(--gold-text); }
.nav a:hover { color: var(--teal); text-decoration: underline; }
/* ---------- Buttons ---------- */
/* ---------- Forms ---------- */
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--teal); box-shadow: var(--shadow-focus); }
input:disabled, select:disabled, textarea:disabled { opacity: 1; color: var(--muted); cursor: not-allowed; }
select, .multi__button {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23bdb4a8' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.multi__button:hover, .multi__button[aria-expanded='true'] { border-color: var(--teal); }
.field__hint, .field__hint a { font-size: var(--fs-sm); }
/* ---------- Sections ---------- */
.section + .section { border-top: 1px solid var(--line); }
/* ---------- Cards ---------- */
/* Status badges: icon + text on light chips with dark text. */
/* ---------- Panels, filters, dialogs ---------- */
.panel, .filters, details, .search-hits li, .event__date { background: var(--surface); border: 1px solid var(--line); box-shadow: none; }
.panel, .filters { border-radius: var(--radius); }
/* ---------- Calendar, posts, account ---------- */
/* Staff-edited text */
/* Staff-picked text colors were chosen for a light page; on the dark theme each maps to a readable equivalent,
   and highlighted text goes dark so it reads on its light highlight. */
:is(.prose, [data-content], #faq-list, .page-body, .lede) :is([style*="color: rgb(22, 22, 22)"], [style*="color:#161616"], [style*="color: #161616"]) { color: inherit !important; }
:is(.prose, [data-content], #faq-list, .page-body, .lede) :is([style*="color: rgb(0, 0, 0)"], [style*="color:#000000"], [style*="color: #000000"], [style*="color: #000"]) { color: inherit !important; }
:is(.prose, [data-content], #faq-list, .page-body, .lede) :is([style*="color: rgb(91, 91, 91)"], [style*="color:#5b5b5b"], [style*="color: #5b5b5b"]) { color: var(--muted) !important; }
:is(.prose, [data-content], #faq-list, .page-body, .lede) :is([style*="color: rgb(200, 16, 46)"], [style*="color:#c8102e"], [style*="color: #c8102e"]) { color: var(--error) !important; }
:is(.prose, [data-content], #faq-list, .page-body, .lede) :is([style*="color: rgb(164, 0, 29)"], [style*="color:#a4001d"], [style*="color: #a4001d"]) { color: var(--error) !important; }
:is(.prose, [data-content], #faq-list, .page-body, .lede) :is([style*="color: rgb(22, 114, 58)"], [style*="color:#16723a"], [style*="color: #16723a"]) { color: var(--ok) !important; }
:is(.prose, [data-content], #faq-list, .page-body, .lede) :is([style*="color: rgb(26, 95, 255)"], [style*="color:#1a5fff"], [style*="color: #1a5fff"]) { color: var(--teal) !important; }
:is(.prose, [data-content], #faq-list, .page-body, .lede) :is([style*="color: rgb(122, 63, 176)"], [style*="color:#7a3fb0"], [style*="color: #7a3fb0"]) { color: var(--violet) !important; }
:is(.prose, [data-content], #faq-list, .page-body, .lede) :is([style*="color: rgb(179, 89, 0)"], [style*="color:#b35900"], [style*="color: #b35900"]) { color: var(--warn) !important; }
:is(.prose, [data-content], #faq-list, .page-body, .lede) [style*='background'] { color: #161616 !important; }
.lede blockquote a, .page-body blockquote a, #faq-list blockquote a { color: var(--on-accent); }
/* ---------- Newsletter + footer ---------- */
/* The email-list embed is the shop's own pasted code (any service) and brings its own styles. */
#newsletter-form { max-width: 100%; }
#newsletter-form iframe { max-width: 100%; }
@media (forced-colors: active) {
  input, select, textarea, .btn { border: 1px solid ButtonText; }
  .hero { background-image: none; }
  a:focus-visible, button:focus-visible, input:focus, select:focus, textarea:focus { outline: 3px solid Highlight; }
}

/* ---------- Loading spinner ---------- */
/* While anything on the page is loading (aria-busy, or "Loading…" text) the page dims and a small
   spinner sits in the middle of the window. Clicks pass through so a stuck load never traps anyone. */
@keyframes spin { to { transform: rotate(360deg); } }
body:has([aria-busy="true"], .loading)::before {
  content: ""; position: fixed; inset: 0; z-index: var(--z-busy); pointer-events: none;
  background: rgb(0 0 0 / .35);
}
body:has([aria-busy="true"], .loading)::after {
  content: ""; position: fixed; top: 50%; left: 50%; z-index: calc(var(--z-busy) + 1); pointer-events: none;
  width: 28px; height: 28px; margin: -14px 0 0 -14px; box-sizing: border-box;
  border: 3px solid rgb(255 255 255 / .35); border-top-color: #fff; border-radius: 50%;
  animation: spin var(--dur-spin) linear infinite;
}
.loading { text-align: center; color: var(--muted); }
.empty.loading { border: 0; }
@media (prefers-reduced-motion: reduce) {
  body:has([aria-busy="true"], .loading)::after { animation-duration: var(--dur-spin-calm); }
}
/* ---------- Pull list app (app.html) ----------
   The account page as an installed app: the shop's brand on top, one view at a time, a tab bar at the foot. The
   header and tab bar clear the phone's notch and home bar (viewport-fit=cover). */
[data-page="app"] #site-header { padding-top: env(safe-area-inset-top); }
/* Taps answer the way a native app's do: no grey flash over what's tapped (each control shows its own press below), no
   text selected by a long press on the app's chrome, and no "Save image" menu from pressing a cover. */
[data-page="app"] { -webkit-tap-highlight-color: transparent; }
[data-page="app"] :is(.tab-bar, .app-bar, .app-view__title, .app-shelf__head, .btn, .link-button, .dialog__close) { -webkit-user-select: none; user-select: none; }
[data-page="app"] :is(img, .tab-bar a, .app-bar a) { -webkit-touch-callout: none; }
[data-page="app"] .btn:active { transform: scale(var(--press-scale)); filter: var(--press-dim); }
[data-page="app"] .link-button { display: inline-flex; align-items: center; min-height: var(--tap); } /* Sign out, See all, Turn off: touch targets on a phone */
[data-page="app"] .link-button:active { opacity: var(--press-fade); }
[data-page="app"] :is(.card__open, .account-line__open):active .cover { filter: var(--press-dim); }
[data-page="app"] :is(.app-bar__search, .account-line__remove, .app-install__close, .dialog__close, .app-shop__links a):active { background: var(--raised); }
/* Switching tabs cross-fades the views (js/pages/app.js, View Transitions); the header and tab bar stay still. */
/* Covers fade in as they load (js/pages/app.js sets .fade-covers and .is-loaded), over a placeholder of their own
   shape on the box around them, so nothing pops or jumps. */
.fade-covers img.cover { opacity: 0; transition: opacity var(--dur-slide) ease-out; }
.fade-covers img.cover.is-loaded { opacity: 1; }
[data-page="app"] :is(.card__media, .account-line__open, .title-modal__cover) { background: var(--raised); border-radius: var(--radius-sm); }
[data-page="app"] #site-header { view-transition-name: app-header; }
[data-page="app"] .tab-bar { view-transition-name: app-tabs; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--dur); }
@media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none; } }
/* Loading in the app: a pulsing block where the view will be, not the website's dimmer and spinner. Screen readers
   still hear its "Loading…"; the app's loading screen waits until none is showing (js/pages/app.js). */
body[data-page="app"]:not(:has([aria-busy="true"]))::before, body[data-page="app"]:not(:has([aria-busy="true"]))::after { content: none; }
/* The skeleton's look: Cards / grids. Its "Loading…" is still read out but pushed out of the box, not made transparent
   (transparent text fails the contrast check and shows again when a visitor overrides page colors). */
[data-page="app"] .empty.loading { min-height: 240px; overflow: hidden; white-space: nowrap; text-indent: 100vw; }
[data-page="app"] #site-header:empty { min-height: var(--app-bar-h); }
.app-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); min-height: var(--app-bar-h); }
.app-bar .brand { min-height: var(--tap); } /* the shop's name goes to My List: a full touch target, not a 22px line */
.app-bar .brand__logo { max-height: 40px; }
.app-bar .brand__name { font-size: calc(1.25rem * var(--display-scale)); }
/* The search button: a magnifier that opens the search under the header; pressed while it's open. */
.app-bar__search { flex: none; display: grid; place-items: center; width: var(--tap); height: var(--tap); margin-right: calc(-1 * var(--sp-10)); padding: 0; border: 0; border-radius: 50%; background: none; color: var(--ink); cursor: pointer; }
.app-bar__search[aria-expanded="true"] { background: var(--surface); color: var(--gold-text); }
.app-bar__search svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; }
.app-main { padding: var(--sp-16) 0 calc(var(--tab-bar-h) + var(--sp-24) + env(safe-area-inset-bottom)); }
.app-view > * + *, [data-shop] > * + * { margin-top: var(--sp-16); }
[data-shop] > .app-shop__links { margin-top: var(--sp-24); }
.app-view__title { font-size: var(--fs-title); margin: 0 0 var(--sp-12); }
/* Every view's sections: the title above, the panel under it (js/pages/account.js titled()). */
.app-view > .app-section + .app-section { margin-top: var(--sp-32); }
.app-look { margin-top: var(--sp-32); }   /* Appearance, under the Account view */
.app-powered { margin: var(--sp-32) 0 0; text-align: center; font-size: var(--fs-xs); color: var(--muted); }   /* last on the Account view */
/* Hot: rows of cards to swipe through, running to the screen's edges. */
.app-shelf + .app-shelf { margin-top: var(--sp-32); }
.app-shelf__head { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-12); }
.app-shelf__head h3 { margin: 0; font-size: var(--fs-sub); }
.app-shelf__head .link-button { flex: none; font-size: var(--fs-sm); font-weight: 700; }
.app-shelf__lede { margin: 0 0 var(--sp-12); color: var(--muted); font-size: var(--fs-sm); }
.app-shelf__row { display: grid; grid-auto-flow: column; grid-auto-columns: min(calc((100% - 2 * var(--sp-12)) / 2.5), 200px); gap: var(--sp-12); overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); margin-inline: calc(-1 * var(--gutter)); padding: 0 var(--gutter) var(--sp-8); }
/* The row holds the cards' hidden screen-reader text (position: absolute), so it must be their containing block:
   otherwise that text sits outside the row and the whole page scrolls sideways. */
.app-shelf__row { position: relative; }
/* Phones swipe the rows, so the scrollbar goes; a mouse keeps it, as its only way to scroll them. */
@media (pointer: coarse) {
  .app-shelf__row { scrollbar-width: none; }
  .app-shelf__row::-webkit-scrollbar { display: none; }
}
.app-shelf__row > * { scroll-snap-align: start; display: grid; }
/* Hot's cards are shorter than the website's: tighter body, smaller lines, a title of at most two lines, and the
   button label on one line. The cut-off date stays ("Add by tonight"); the day after it goes. The clamp sits on the
   title's button, so its focus ring and stretched tap area (positioned on .card__title) aren't cut. */
.app-shelf__row .card__body { padding: var(--sp-8); gap: var(--sp-4); }
.app-shelf__row .card__title { font-size: var(--fs-ui); }
.app-shelf__row .card__title-open { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.app-shelf__row .card__meta { font-size: var(--fs-xs); }
.app-shelf__row .foc .card__meta { display: none; }
.app-shelf__row .card__foot { padding-top: var(--sp-4); }
.app-shelf__row .card .btn { padding-inline: var(--sp-4); font-size: var(--fs-2xs); }
/* Search, from the header's button over any tab: the box slides down from behind the header over the page, wherever
   it is scrolled, and stays fixed under the header. It sits under the header (z-index), so it comes out from behind
   it. Results stand in for the tab while the box has words in it, starting below the box. */
@keyframes search-slide { from { transform: translateY(-100%); } }
.app-search > form { position: fixed; top: var(--app-header-bottom); left: 0; right: 0; z-index: var(--z-popover); padding: var(--sp-10) max(var(--gutter), calc((100% - var(--max)) / 2 + var(--gutter))); background: var(--paper); border-bottom: var(--border); box-shadow: var(--shadow-menu); animation: search-slide var(--dur-slide) ease-out; }
.app-search > form input { width: 100%; }
.app-search:has([data-search-results]:not([hidden])) { padding-top: calc(var(--field-h) + 2 * var(--sp-10)); }
@media (prefers-reduced-motion: reduce) { .app-search > form { animation: none; } }
/* My List's pickup code (js/pages/account.js): a QR code staff scan, and the number to type into Customers. The code
   stays dark on white in every theme, as scanners need. */
.app-pickup { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-12) var(--sp-16); margin: 0 0 var(--sp-12); padding: var(--sp-12); background: var(--surface); border: var(--border); border-radius: var(--radius); }
.app-pickup > div:last-child { flex: 1 1 140px; }
.app-pickup__name { flex: 1 0 100%; margin: 0; font-family: var(--font-heading); font-size: var(--fs-title); font-weight: 700; line-height: 1.2; overflow-wrap: anywhere; }
.app-pickup__qr { flex: none; width: 112px; padding: var(--sp-4); border: 0; background: white; border-radius: var(--radius-sm); cursor: zoom-in; }
.app-pickup__qr svg, .pickup-full__qr svg { display: block; width: 100%; height: auto; fill: black; } /* the QR code, dark on white, small and full screen */
.app-pickup__label { margin: 0; color: var(--muted); font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.app-pickup__code { margin: 0 0 var(--sp-4); font-family: var(--font-display); font-size: calc(1.6rem * var(--display-scale)); letter-spacing: var(--display-tracking); line-height: 1.1; }
.app-pickup .card__meta { margin: 0; }
/* Tapped, the code fills the screen (js/app-pickup.js): dark on white whatever the page, the name and number under it,
   big enough to scan from across the counter. The screen is kept awake meanwhile. */
.pickup-full { width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh; margin: 0; padding: calc(var(--sp-24) + env(safe-area-inset-top)) var(--gutter) calc(var(--sp-24) + env(safe-area-inset-bottom)); border: 0; border-radius: 0; background: white; color: black; }
.pickup-full[open] { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-12); text-align: center; }
.pickup-full::backdrop { background: white; }
.pickup-full__qr { width: min(80vw, 60dvh, 420px); }
.pickup-full__name { margin: var(--sp-8) 0 0; font-family: var(--font-heading); font-size: var(--fs-title); font-weight: 700; overflow-wrap: anywhere; }
.pickup-full__code { margin: 0; font-family: var(--font-display); font-size: calc(2.4rem * var(--display-scale)); letter-spacing: var(--display-tracking); line-height: 1; }
.pickup-full__hint { margin: 0; font-size: var(--fs-sm); }
/* ShopDialog's round close button, in the corner; on the always-white card it's black, and keyboard focus fills it
   black, as the page's focus blue (made for the page, not for white) wouldn't show. Every other focus ring in the card
   is black for the same reason. */
.pickup-full__close { position: absolute; top: calc(var(--sp-8) + env(safe-area-inset-top)); right: calc(var(--sp-8) + env(safe-area-inset-right)); border-color: rgb(0 0 0 / .45); color: black; }
.pickup-full__close:hover { background: rgb(0 0 0 / .08); border-color: black; }
.pickup-full__close:focus-visible { background: black; border-color: black; color: white; }
.pickup-full :focus-visible { outline-color: black; }
/* My List's date headings stay pinned under the header while their titles scroll under them, as in a native
   grouped list; the next one slides over it. */
[data-page="app"] .account-group { position: sticky; top: var(--app-header-bottom); z-index: calc(var(--z-raised) + 1); margin-bottom: 0; padding-top: var(--sp-12); background: var(--paper); }
[data-page="app"] .panel .account-group { background: var(--surface); } /* My List sits in a panel: the band is the panel's color */
/* The first-run welcome on My List, until "Got it". */
.app-welcome { margin: 0 0 var(--sp-20); padding: 0 0 var(--sp-20); border-bottom: var(--border); }
.app-welcome__title { margin: 0 0 var(--sp-8); font-size: var(--fs-sub); }
.app-welcome__steps { margin: 0 0 var(--sp-16); padding-left: var(--sp-20); }
.app-welcome__steps li + li { margin-top: var(--sp-8); }
.app-welcome__actions { display: flex; flex-wrap: wrap; gap: var(--sp-12); }
/* The app's loading screen (app.html): the shop's logo and name on its page color, over the status bar too. Script
   fades it once the first view is drawn; with no script it still fades after --dur-splash-max. */
@keyframes splash-out { to { opacity: 0; visibility: hidden; } }
.app-splash { position: fixed; inset: 0; z-index: var(--z-splash); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-16); padding: var(--gutter); background: var(--paper); text-align: center; transition: opacity var(--dur), visibility var(--dur); animation: splash-out var(--dur) var(--dur-splash-max) forwards; }
.app-splash.is-gone { opacity: 0; visibility: hidden; pointer-events: none; }
.app-splash__logo { width: auto; max-width: 60%; max-height: 120px; }
.app-splash__name { margin: 0; font-family: var(--font-display); font-weight: var(--display-weight); font-size: calc(1.6rem * var(--display-scale)); letter-spacing: var(--display-tracking); text-transform: var(--display-case); color: var(--cream); line-height: 1.1; }
.app-splash__name:empty { display: none; }
@media (prefers-reduced-motion: reduce) {
  .app-splash { transition: none; animation-duration: var(--dur-press); }
}
/* A strip under the header: offline, or a new version ready. */
.app-note, .app-install { display: flex; align-items: center; gap: var(--sp-12); margin-top: var(--sp-12); padding-block: var(--sp-12); background: var(--surface); border: var(--border); border-radius: var(--radius); }
.app-note__text, .app-install__text { flex: 1; margin: 0; font-size: var(--fs-sm); }
.app-note .btn, .app-install .btn { flex: none; }
/* The list as last drawn, shown offline: read-only, so its controls are left out. */
.account-saved-list .account-line__swipe,
.account-saved-list .account-line__controls, .account-saved-list .account-move, .account-saved-list .form-error { display: none; }
.app-install__close { flex: none; width: var(--tap); height: var(--tap); border: 0; background: none; color: var(--muted); font-size: var(--fs-lede); cursor: pointer; }
.app-install__close:hover { color: var(--ink); }
/* Signed out, or finishing a first sign-in, the app is just the sign-in form: no tab bar or search (js/pages/app.js). */
.app-locked .tab-bar, .app-locked .app-bar__search { display: none; }
.app-locked .app-main { padding-bottom: calc(var(--sp-24) + env(safe-area-inset-bottom)); }
.tab-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-bar); background: var(--surface); border-top: 1px solid var(--line); padding-bottom: env(safe-area-inset-bottom); }
.tab-bar ul { display: grid; grid-template-columns: repeat(4, 1fr); max-width: var(--max); margin: 0 auto; padding: 0; list-style: none; }
.tab-bar a { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-2); min-height: var(--tab-bar-h); padding: var(--sp-6) var(--sp-4); color: var(--muted); font-size: var(--fs-2xs); font-weight: 700; text-decoration: none; }
.tab-bar a:hover { color: var(--ink); }
.tab-bar a[aria-current="page"] { color: var(--ink); box-shadow: inset 0 3px 0 var(--gold); }
.tab-bar a[aria-current="page"] svg { stroke: var(--gold-text); }
/* High-contrast modes drop the shadow that marks the current tab: give it a real edge there. */
@media (forced-colors: active) { .tab-bar a[aria-current="page"] { border-top: 3px solid Highlight; } }
.tab-bar svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: transform var(--dur-press); }
.tab-bar a:active svg { transform: scale(var(--press-scale-icon)); }
.tab-bar__count { position: absolute; top: var(--sp-4); left: calc(50% + 8px); min-width: 18px; padding: 0 var(--sp-4); border-radius: var(--radius-pill); background: var(--gold); color: var(--on-accent); font-size: var(--fs-3xs); line-height: 18px; text-align: center; }
.app-shop { text-align: center; }
.app-shop__logo { max-height: 96px; width: auto; margin: 0 auto var(--sp-12); }
.app-shop__name { margin: 0; font-family: var(--font-display); font-weight: var(--display-weight); font-size: calc(1.6rem * var(--display-scale)); letter-spacing: var(--display-tracking); text-transform: var(--display-case); color: var(--cream); line-height: 1.1; }
.app-shop__tagline { margin: var(--sp-6) 0 0; color: var(--muted); }
.app-shop__place { margin-top: var(--sp-24); padding-top: var(--sp-24); border-top: var(--border); }
.app-shop__place-name { font-size: var(--fs-sub); margin: 0; }
.app-shop__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-12); margin: var(--sp-16) 0 var(--sp-20); }
.app-shop__place-name + .app-shop__actions { margin-top: var(--sp-12); }
.app-shop__email { margin: var(--sp-24) 0 var(--sp-16); padding-top: var(--sp-16); border-top: var(--border); }
.app-shop__email a { display: inline-flex; align-items: center; min-height: var(--tap); }
.app-shop__address { font-style: normal; margin: 0 0 var(--sp-16); }
.app-shop__sub { font-size: var(--fs-compact); margin: var(--sp-16) 0 var(--sp-6); }
.app-shop .hours div { margin-inline: auto; }
.app-shop .socials { justify-content: center; }
.app-shop__links { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8); }
.app-shop__links a { display: flex; align-items: center; justify-content: center; min-height: 48px; padding: var(--sp-8); background: var(--surface); border: var(--border); border-radius: var(--radius); font-weight: 700; text-decoration: none; }
.app-shop__links a:hover { background: var(--raised); }
/* My List in the app: a bigger cover, the title across the rest of the line, copies and a remove icon under the details. */
.account-line--app { display: grid; grid-template-columns: 116px minmax(0, 1fr); align-items: start; gap: var(--sp-14); padding: var(--sp-14) 0; }
.account-line--app .cover { width: 116px; }
.account-line__open { display: block; flex: none; padding: 0; border: 0; background: none; cursor: pointer; }
.account-line__open:hover .cover { filter: brightness(1.08); }
/* Holds the title button's stretched tap area (.card__title-open::after), as .card__title does on a card: without it
   the area grows to the page and covers the estimated total. */
.account-line__title { display: block; position: relative; }
.account-line--app .account-line__title { font-size: var(--fs-compact); line-height: 1.25; }
.account-line--app .account-line__status { text-align: left; }
.account-line__controls { display: flex; align-items: center; gap: var(--sp-8); margin-top: var(--sp-6); }
.account-line__qty-label { margin: 0; font-size: var(--fs-sm); font-weight: 700; color: var(--muted); }
.account-line__remove { display: grid; place-items: center; width: var(--tap); height: var(--tap); margin-left: var(--sp-4); padding: 0; border: 0; border-radius: var(--radius-sm); background: none; color: var(--muted); cursor: pointer; }
.account-line__remove:hover { color: var(--error); background: var(--raised); }
/* Swipe a title left to remove it (js/app-swipe.js sets --swipe and the classes): the row slides left over a red
   Remove that grows from its right edge; a short swipe leaves 88px of it to tap, a long one removes on release.
   The row only takes sideways drags (pan-y), so the page still scrolls. */
.account-line--app { position: relative; touch-action: pan-y; }
.account-line--app > :not(.account-line__swipe) { transform: translateX(calc(-1 * var(--swipe, 0px))); }
.account-line__swipe { position: absolute; top: 0; right: 0; bottom: 0; z-index: var(--z-raised); display: flex; align-items: center; justify-content: flex-end; width: var(--swipe, 0px); padding: 0; overflow: hidden; border: 0; border-radius: var(--radius-sm); background: var(--swipe-remove); color: var(--on-swipe-remove); font: 700 var(--fs-sm)/1 var(--font-body); white-space: nowrap; cursor: pointer; }
.account-line__swipe > span { flex: none; width: var(--swipe-open); text-align: center; }
.account-line--app:not(.is-swiped) .account-line__swipe { visibility: hidden; }
.account-line--app.is-armed .account-line__swipe { justify-content: center; }
.account-line--app.is-settling > :not(.account-line__swipe), .account-line--app.is-settling .account-line__swipe { transition: transform var(--dur-sheet) ease-out, width var(--dur-sheet) ease-out; }
.account-line__remove svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* Pull down to refresh: a round badge drops from under the header, its arrow turning as it's pulled, gold once letting
   go will refresh, then spinning until the views are drawn again. js/pages/app.js sets --pull, --pull-turn, --pull-top. */
html:has(body[data-page="app"]) { overscroll-behavior-y: none; }
/* Keyboard focus never lands under the app's sticky header with a pinned date heading, or under the tab bar: the
   browser keeps this much room when it scrolls a focused control into view (WCAG 2.4.11). The top room follows the
   heading's own text size (Shop Settings → Fonts), with its padding and edge. */
html:has(body[data-page="app"]) { scroll-padding-top: calc(var(--app-header-bottom) + 2 * var(--fs-sub) + var(--sp-24)); scroll-padding-bottom: calc(var(--tab-bar-h) + env(safe-area-inset-bottom) + var(--sp-8)); }
.app-pull { position: fixed; top: var(--pull-top, 0px); left: 50%; z-index: var(--z-popover); display: grid; place-items: center; width: 40px; height: 40px; margin-left: -20px; border: var(--border); border-radius: 50%; background: var(--surface); box-shadow: var(--shadow-menu); color: var(--muted); opacity: 0; pointer-events: none; transform: translateY(calc(var(--pull, 0px) - 48px)); }
.app-pull.is-pulling, .app-pull.is-refreshing { opacity: 1; }
.app-pull.is-settling { transition: transform var(--dur), opacity var(--dur); }
.app-pull svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; transform: rotate(calc(var(--pull-turn, 0) * 270deg)); }
.app-pull.is-ready, .app-pull.is-refreshing { color: var(--gold-text); }
.app-pull.is-refreshing svg { animation: spin var(--dur-spin) linear infinite; }
@media (prefers-reduced-motion: reduce) {
  .app-pull.is-settling { transition: none; }
  .app-pull.is-refreshing svg { animation-duration: var(--dur-spin-calm); }
}
/* App → Account → Notifications */
.push-on { margin: 0 0 var(--sp-8); color: var(--ok); font-weight: 700; }
.push-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-16); margin-top: var(--sp-12); }
