/* yourque.app, shared stylesheet. The tokens, the wordmark font, the reset, the
   column, the nav, the notify block, the footer, the buttons and the motion rules
   live here so every page draws them from one place. Rules that belong to one
   page stay in that page's own <style> block, after this file. */

/* Lato Black 900, self-hosted, SIL OFL 1.1: see /fonts/OFL.txt. This file is the
   subset the wordmark needs (the glyphs Y o u r e and a space); the Q is an inline
   SVG. The full face stays at /fonts/Lato-Black.woff2. */
@font-face {
  font-family: "Lato";
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url("/fonts/Lato-Black-wordmark.woff2") format("woff2");
}
/* The ten digits of the same face (30 Oct 2026), a second subset for the step
   numbers on the home page. unicode-range keeps it unfetched on a page that sets
   no digit in Lato, and, declared after the wordmark face, makes it the face a
   digit takes. Lato is for the wordmark and digits only: the full face lacks the
   Polish accents, the Turkish dotted and dotless i and all CJK. */
@font-face {
  font-family: "Lato";
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url("/fonts/Lato-Black-digits.woff2") format("woff2");
  unicode-range: U+30-39;
}

/* Dark is the default every visitor gets. The light theme below is opt-in,
   chosen through the header switch, which sets data-theme="light" on <html>.
   The OS preference is deliberately not consulted: Quincy's decision, 27 Sep
   2026, replacing the previous cream default plus prefers-color-scheme pair. */
:root {
  color-scheme: dark;
  --bg: #141714;
  --surface: #1C211D;
  --text: #ECEAE0;
  --muted: #A3AA98;
  --accent: #8FB49E;
  --gold: #D4B276;
  --gold-soft: #D4B276;
  --gold-text: #D4B276;
  --border: #2C332D;
  --band-bg: #1A2B21;
  --band-text: #F3F1E9;
  --band-muted: #AEBBAB;
  --star: #D4B276;
  --star-empty: #3A423B;
  --band-link: #D4B276;
  /* The sitewide type scale and section spacing (30 Oct 2026), referenced by each page's own rules. */
  --title-size: clamp(1.9rem, 1.15rem + 2.4vw, 3.25rem);
  --section-head-size: clamp(1.75rem, 1.1rem + 2.4vw, 3rem);
  --article-head-size: clamp(1.5rem, 1.15rem + 1vw, 2rem);
  --section-space: clamp(72px, 8vw, 120px);
}

/* Text gold. --gold is 2.92:1 on the cream, fine for rules, dots and large
   numbers but not for small text, so every gold text under 1.2rem uses
   --gold-text instead: 4.95:1 on the page and 5.35:1 on a card in light,
   8.97:1 and 8.12:1 in dark, where it is simply the same value as --gold. The
   star tokens carry the same pair. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #F3F1E9;
  --surface: #FBFAF5;
  --text: #26302A;
  --muted: #66705F;
  --accent: #2E4A3C;
  --gold: #A8894E;
  --gold-soft: #C9A96A;
  --gold-text: #7E6430;
  --border: #E3E0D4;
  --band-bg: #2E4A3C;
  --band-text: #F3F1E9;
  --band-muted: #C8CFC3;
  --star: #7E6430;
  --star-empty: #D3CFC0;
  /* The link in the green band. --gold-soft (#C9A96A) is 4.33:1 on the band,
     under the 4.5:1 small text needs; #D4B276 is 4.83:1 there (27 Oct 2026
     audit). The rule and the destiny line keep --gold-soft: large or decorative. */
  --band-link: #D4B276;
}

/* ---------- Reset and body ---------- */

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); }
[hidden] { display: none !important; }

/* One column width sitewide: 680px for reading copy, 960px for cards and grids.
   With the 24px padding the wide column's content runs 184 to 1096 at 1280px,
   the same edges as the nav. */
.col { max-width: 680px; margin: 0 auto; padding: 0 24px; }
.col.wide { max-width: 960px; }

.eyebrow {
  font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold-text); margin-bottom: 12px;
  text-wrap: balance;
}

/* ---------- Nav ---------- */

/* The bar stays (30 Oct 2026): sticky at the top, the page showing through it
   at 86 percent behind a blur, so the next step is one tap away from anywhere on
   the page. The solid colour first is the fallback for a browser without
   color-mix. Sticky is positioned, so the phone panel below still hangs off it. */
.nav {
  position: sticky; top: 0; z-index: 40;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}
/* Every in-page target (#get, #plus, #shop, the FAQ anchors of the search pages)
   would land under the bar: its height (57px on a desktop, 57 on a phone with
   the menu button) plus a breath keeps the target in view. */
[id] { scroll-margin-top: 72px; }
/* #get is the closing panel (Free to start) since 30 Oct 2026, the target of
   the bar's Get the app on every page; the panel is a reveal block and rises
   14px as it comes in, so its margin is the bar (57px below 1000px) plus a
   16px breath plus that rise. Until then the home hero's badge row carried
   the id and an 86px margin of its own. */
#get { scroll-margin-top: 87px; }
.nav-inner {
  max-width: 960px; margin: 0 auto; padding: 8px 24px;
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 10px;
}
.brand {
  display: inline-flex; align-items: center; gap: 10px;
  font-weight: 700; font-size: 1.02rem;
  color: var(--text); text-decoration: none;
}
/* The header mark is the app icon itself, the cream Q tile, the same PNG that
   serves as the apple-touch-icon, clipped to the tile's 8px radius. In light the
   cream tile sits on a cream page, so a 1px outline in #C7CCC3 is drawn outside
   the box with a box-shadow, which changes no layout; dark needs none. Option
   C1, Quincy's pick, 25 Oct 2026. */
.brand .bmark {
  width: 28px; height: 28px; border-radius: 8px; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
}
.brand .bmark img { display: block; width: 28px; height: 28px; }
:root[data-theme="light"] .brand .bmark { box-shadow: 0 0 0 1px #C7CCC3; }
/* The wordmark: Lato Black at the element's own font size, letter-spacing 0. The inline svg box is the ring's outer square: its height is the cap height and its bottom edge sits on the baseline (cap unit where supported, em fallback first). */
.wordmark{font:900 1em/1 "Lato","Segoe UI",system-ui,sans-serif;letter-spacing:0;white-space:nowrap;display:inline-block}
.wordmark svg{display:inline-block;vertical-align:baseline;overflow:visible;width:.7285em;height:.7285em;width:1cap;height:1cap;margin:0 0.0358125em 0 0.03125em}
/* The gaps in the bar (12 here, 14 either side of the Get the app pill, 16
   between the two controls, and 10px of side padding on the two control pills)
   are what lets five links, the pill, the theme switch and the language
   switcher share one row at desktop widths in every language: the row has
   797px beside the brand. With the plain Get the app link (29 Oct 2026) the
   French bar measured 826 and the Japanese 798 at the old gaps of 18 and 20;
   as the gold pill (30 Oct 2026, 16px of padding each side) French needed 15px
   more than the row and Japanese 7, so the gaps and paddings came down once
   more (French keeps 21px to spare, Japanese 21, measured in Chrome on
   Windows; a platform font a few percent wider still fits). */
.links { display: flex; gap: 12px; font-size: 0.92rem; flex-wrap: wrap; }
:lang(fr) .links { gap: 10px; }
/* Each link carries 8px of vertical padding so its tap target is at least 24px
   tall on a phone; the bar's own padding is 6px less than it was, so the nav
   keeps its height at desktop widths. */
.links a {
  color: var(--muted); text-decoration: none;
  position: relative; padding: 8px 0; transition: color 0.2s ease;
}
.links a::after {
  content: ""; position: absolute; left: 0; bottom: 4px;
  width: 100%; height: 1.5px; border-radius: 1px;
  background: var(--gold);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.25s ease;
}
.links a:hover { color: var(--text); }
.links a:hover::after, .links a:focus-visible::after { transform: scaleX(1); }
.links a.active { color: var(--gold-text); font-weight: 600; }
/* Phone widths without script (the menu below needs the js class): the links
   wrap under the brand, so spread them edge to edge instead of packing left. */
@media (max-width: 499px) {
  .links { width: 100%; justify-content: space-between; gap: 0; }
}
/* Get the app (29 Oct 2026), the one gold pill of the bar since 30 Oct 2026. A
   direct child of .nav-inner, outside the panel, so one element serves every
   width: in the bar beside the menu button below 1000px, between the links and
   the controls from 1000px, where the panel is display: contents and the three
   are ordered into place. site.js turns it into the store link on a phone. */
.nav-get {
  display: inline-block; white-space: nowrap;
  background: var(--gold); color: #141714;
  font-size: 0.92rem; font-weight: 700; line-height: 1.2;
  padding: 7px 14px; border-radius: 999px; text-decoration: none;
  transition: filter 0.2s ease;
}
.nav-get:hover { filter: brightness(1.06); }
.nav-get:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
@media (min-width: 1000px) {
  .links { order: 1; margin-left: auto; }
  .nav-get { order: 2; margin-left: 4px; }
  .nav-controls { order: 3; margin-left: 4px; }
}
@media (max-width: 999px) {
  .nav-get { margin-left: auto; font-size: 0.85rem; padding: 6px 13px; }
}

/* ---------- Phone nav: one row and a menu button ----------
   Under 1000px the bar is the brand, the pill and one button; the links, the
   theme switch and the language switcher sit in a panel that drops down from the
   bar when the button is pressed (site.js toggles nav-open on the bar and
   aria-expanded on the button; Escape and a tap outside close it). The panel
   floats over the page the way the language list does, so nothing shifts.
   Everything hangs on the js class: without script the button never shows
   and the bar wraps as it did before, every control still in reach. Measured
   27 Oct 2026 at 360x640: the wrapped bar was 153px tall, 193 in Japanese and
   211 in Brazilian Portuguese, and the store badges began below the first
   screen in all twelve languages. The button is 40px square, the height of
   the pills, so the bar keeps its desktop height. The panel's absolute position
   hangs off the bar, which is sticky (above) and so positioned. The phone
   layout runs to 999px since 30 Oct 2026: with the row from 640px it wrapped
   to two rows (105px) between about 650 and 925px (English to 825, German to
   850, Japanese to 925), and at 775px a tap on Get the app landed its target
   under the bar; from 1000px the row fits in every language with 20px to
   spare (French and Japanese, measured in Chrome on Windows). */
.nav-menu {
  display: none; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0; border-radius: 12px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  cursor: pointer;
}
.nav-menu:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nav-menu-bars, .nav-menu-bars::before, .nav-menu-bars::after {
  display: block; width: 18px; height: 2px; border-radius: 1px; background: currentColor;
  transition: transform 0.2s ease, background 0.2s ease;
}
.nav-menu-bars { position: relative; }
.nav-menu-bars::before, .nav-menu-bars::after { content: ""; position: absolute; left: 0; }
.nav-menu-bars::before { top: -6px; }
.nav-menu-bars::after { top: 6px; }
.nav-menu[aria-expanded="true"] .nav-menu-bars { background: transparent; }
.nav-menu[aria-expanded="true"] .nav-menu-bars::before { transform: translateY(6px) rotate(45deg); }
.nav-menu[aria-expanded="true"] .nav-menu-bars::after { transform: translateY(-6px) rotate(-45deg); }
/* The theme switch and the language switcher, one row inside .nav-right. */
.nav-controls { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
@media (max-width: 999px) {
  .js .nav-menu { display: inline-flex; }
  .js .nav-right { display: none; }
  .js .nav-open .nav-right {
    display: flex; flex-direction: column; align-items: stretch; gap: 16px;
    position: absolute; top: 100%; left: 0; right: 0; z-index: 40;
    padding: 6px 24px 18px;
    background: var(--surface); border-bottom: 1px solid var(--border);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.18);
  }
  .js .nav-open .links { flex-direction: column; gap: 0; width: auto; }
  .js .nav-open .links a { padding: 11px 0; font-size: 1rem; border-bottom: 1px solid var(--border); }
  .js .nav-open .links a::after { display: none; }
  .js .nav-open .nav-controls { justify-content: space-between; }
}

/* ---------- Notify ---------- */

.notify {
  padding: 72px 24px;
  background: var(--surface);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  text-align: center;
}
/* The closing block as a panel (30 Oct 2026): the column carries the surface
   with a gold hairline and its own padding, so the last thing on the page is
   framed; the band's 24px either side keeps the frame off a phone's edges. The
   label above the heading is the site's gold label, kept gold here against the
   muted paragraph rule below. */
.notify .col { background: var(--surface); border: 1px solid var(--gold-soft); border-radius: 18px; padding: clamp(28px, 4vw, 48px); max-width: 760px; }
.notify .eyebrow { color: var(--gold-text); max-width: none; margin: 0 auto 12px; }
.notify h2 { font-size: 1.5rem; font-weight: 700; letter-spacing: -0.01em; margin-bottom: 16px; }
.notify p { color: var(--muted); max-width: 30em; margin: 0 auto 16px; }
.notify p:last-child { margin-bottom: 0; }
.notify form { margin-top: 24px; display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.notify input[type="email"] {
  font: inherit; padding: 12px 16px;
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--bg); color: var(--text);
  min-width: 240px; flex: 1 1 240px; max-width: 340px;
}
.notify input[type="email"]:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: transparent; }
.notify button {
  font: inherit; font-weight: 600;
  padding: 12px 24px; border: none; border-radius: 12px;
  background: var(--accent); color: var(--bg); cursor: pointer;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.notify button:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(46, 74, 60, 0.28);
}
.notify button:active { transform: translateY(0); box-shadow: none; }
.notify .micro { font-size: 0.85rem; margin-top: 14px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.hidden-field { position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden; }
@media (max-width: 499px) {
  .notify form { gap: 12px; }
  .notify input[type="email"], .notify button { width: 100%; }
  .notify input[type="email"] { max-width: none; }
}

/* ---------- Store badges ---------- */

/* Apple's badge is its SVG at 48px high. Google's PNG (646 x 250) carries a
   transparent margin of 41px on every side, so at 186 x 72 a negative margin
   of 12px trims it to the same 48px badge and the two sit at one height.
   Side by side from 500px, stacked under it. */
.badges { display: flex; justify-content: center; align-items: center; gap: 14px; flex-wrap: wrap; }
.badges a { display: inline-flex; line-height: 0; border-radius: 8px; }
.badges a:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
.badges img { display: block; height: 48px; width: auto; }
.badges a.play img { height: 72px; margin: -12px; }
@media (max-width: 499px) {
  .badges { flex-direction: column; }
}
/* The row that follows the first section of a page (after the moments on
   Features and the blocks on About; the home page's two rows went on 30 Oct
   2026, with Get the app always in the bar): the same markup and class as
   every other row, so site.js tags and counts it with the rest, and some room
   above it. */
.badges.mid { margin-top: 36px; }

/* ---------- Buttons (links styled as buttons; forms style their own) ---------- */

.btn {
  display: inline-block; padding: 12px 22px; border-radius: 12px; text-decoration: none;
  font-weight: 600; font-size: 0.98rem; transition: opacity 0.2s ease;
}
.btn:hover { opacity: 0.88; }
.btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.btn.primary { background: var(--accent); color: var(--bg); }
.btn.secondary { background: transparent; color: var(--accent); border: 1.5px solid var(--accent); }

/* ---------- Text links ---------- */

/* A link in running copy is as tall as its font, about 20px, under the 24px a
   tap target needs (27 Oct 2026 audit: "Read the idea behind it", "Read the
   privacy policy", "Write to us."). 3px above and below on the inline box
   makes the hit area 26px and moves nothing: vertical padding on an inline
   element never changes the line it sits in. Buttons and badges carry a
   class and keep their own padding. */
main p a:not([class]) { padding: 3px 0; }

/* A link that leads on carries an arrow (30 Oct 2026): the more links under the
   home sections, the shop link and the chain link in the band, each the one
   link of a paragraph with this class. Never the nav, the footer or a link
   inside running text. The space before the arrow is no-break, so the arrow
   never wraps on its own. */
.more-link > a::after { content: "\00a0\2192"; }

/* ---------- Footer ---------- */

footer {
  text-align: center; padding: 48px 24px 48px;
  font-size: 0.88rem; color: var(--muted);
  border-top: 1px solid var(--border);
}
/* The notify block carries its own bottom border, so the footer's top border would double it. */
.notify + footer { border-top: none; }
footer .slogan-small { color: var(--gold-text); font-weight: 600; margin-bottom: 12px; }
/* The slogan is two sentences on two lines (Quincy, 30 Oct 2026): common.slogan
   carries each in a span, and the span is a block wherever the footer shows it,
   404 included. */
footer .slogan-small span { display: block; }
footer a { color: var(--muted); }
/* Columns since 30 Oct 2026 (Quincy's pick from the browser mock), on the
   standard pages; 404 and gift keep their own footers and the rules above.
   .foot-grid holds four blocks: the brand (the mark and the wordmark as in the
   nav, the slogan, the four social links), then three nav columns under gold
   labels: YourQue (Features, Philosophy, About, Contact), Guides (the three
   search pages) and Legal (Terms, Privacy). On a phone the brand block takes
   the full width, YourQue and Guides share the next row and Legal follows;
   from 840px the four sit side by side. Under the grid one quiet line,
   .foot-bar: the legal line (the name, KvK and VAT), nothing else. The grid
   and the line share the nav's content width (960 minus its 24px padding each
   side). The padding belongs to the grid's footer only; 404 and gift keep 48/48. */
footer:has(.foot-grid) { padding: 56px 24px 28px; }
.foot-grid {
  max-width: 912px; margin: 0 auto; text-align: left;
  display: grid; grid-template-columns: 1fr 1fr; gap: 32px 24px;
}
.foot-brand { grid-column: 1 / -1; }
@media (min-width: 840px) {
  .foot-grid { grid-template-columns: 1.7fr 1fr 1.3fr 1fr; }
  .foot-brand { grid-column: auto; }
}
/* Every column link reads in the muted ink at rest and keeps it once visited (a
   phone showed a few links warmer than the rest before this was pinned); the
   brand sits in the text colour, as in the mock Quincy approved; on hover and
   keyboard focus each takes the text colour and an underline. The muted ink on
   the page is 4.59:1 in light, above the 4.5 line. */
.foot-grid a, .foot-grid a:visited { color: var(--muted); text-decoration: none; }
.foot-grid a:hover, .foot-grid a:focus-visible { color: var(--text); text-decoration: underline; text-underline-offset: 3px; }
.foot-brand .brand, .foot-brand .brand:visited { font-size: 1.15rem; color: var(--text); }
footer .foot-brand .slogan-small { color: var(--text); font-weight: 500; font-size: 0.95rem; line-height: 1.5; margin: 14px 0 12px; max-width: 17em; }
.foot-label { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--gold-text); margin: 0 0 10px; }
.foot-col a { display: block; font-size: 0.92rem; padding: 6px 0; line-height: 1.4; }
.foot-bar {
  max-width: 912px; margin: 24px auto 0; /* the nav's content width: 960 minus its 24px padding each side */
  font-size: 0.78rem; text-align: left;
}
.foot-grid + .foot-bar { margin-top: 40px; padding-top: 18px; border-top: 1px solid var(--border); }
/* The four social links (29 Oct 2026): inline SVG glyphs in the footer's own
   ink, so they follow the theme; each link is a 44px square tap target around a
   22px glyph. In the brand block the row starts at the left edge, the first
   box's 11px pulled out so the glyph lines up with the mark above it. */
.foot-social { display: flex; justify-content: center; gap: 6px; }
.foot-brand .foot-social { justify-content: flex-start; margin-left: -11px; }
.foot-social a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 12px; color: var(--muted);
}
.foot-social a:hover, .foot-social a:focus-visible { color: var(--text); text-decoration: none; }
.foot-social a:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.foot-social svg { display: block; width: 22px; height: 22px; }

/* ---------- Read next ---------- */

/* A row of links to related pages (30 Oct 2026): under the plans on Features
   and after the FAQ on the three search pages. A plain list, wrapping, each
   link with the 26px hit area the paragraph links get. */
.read-next { list-style: none; display: flex; flex-wrap: wrap; gap: 4px 28px; font-weight: 600; }
.read-next a { display: inline-block; padding: 8px 0; }
.read-next.center { justify-content: center; text-align: center; margin-top: 16px; }

/* ---------- Language switcher ----------
   Written by site-tools/localise.mjs: a native details/summary dropdown,
   the same disclosure the FAQ items use, so the browser opens and closes
   it with no script. Collapsed, it names the current language; open, it
   lists all twelve, flag and name together, the current one marked.

   On the seven pages with a header, it sits in .nav-right, top right,
   beside the nav links (.nav-right below). On 404 and gift, which have no
   header to join, the generator adds lang-switcher-floating and it is
   pinned to the top right of the viewport instead. Either way, opening it
   drops the list down as a floating panel so it never pushes the page. */
.nav-right { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
/* From 1000px the panel dissolves (display: contents, declared after the flex
   rule above so it wins at equal specificity): the links, the Get the app pill
   and the controls are then items of the bar's own row, ordered links, pill,
   controls by the rules next to .nav-get. */
@media (min-width: 1000px) { .nav-right { display: contents; } }
.lang-switcher { position: relative; }
.lang-switcher-floating { position: fixed; top: 14px; right: 16px; z-index: 50; }
.lang-current {
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer; list-style: none;
  padding: 7px 10px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface); color: var(--text);
  font-size: 0.82rem; white-space: nowrap;
}
.lang-current::-webkit-details-marker { display: none; }
.lang-current::after { content: '▾'; margin-left: 2px; color: var(--muted); font-size: 0.7em; }
.lang-switcher[open] .lang-current::after { content: '▴'; }
/* Self-hosted SVG flags, not emoji: Windows' system emoji font carries no
   flag glyphs, so Chrome on Windows rendered every one as a bare two-letter
   country code. The files live in /assets/flags/ because the CSP allows
   img-src 'self' only. flex: none keeps the icon its full size inside the
   flex rows of .lang-current and .lang a; block kills the inline baseline
   gap the way line-height: 1 used to for the emoji. */
.lang-flag {
  display: block;
  flex: none;
  width: 20px;
  height: 14px;
  object-fit: cover;
  border-radius: 2px;
}
.lang {
  position: absolute; top: 100%; right: 0; margin-top: 8px; z-index: 1;
  display: flex; flex-direction: column;
  gap: 2px; min-width: 200px; max-height: 70vh; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  padding: 6px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.lang a {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-radius: 8px;
  color: var(--muted); text-decoration: none; font-size: 0.85rem;
}
.lang a:hover { background: var(--bg); color: var(--text); }
.lang a[aria-current="page"] { color: var(--gold-text); font-weight: 600; }
/* Phone widths without script: .links above already goes width:100% here to
   get its own row edge to edge, but that 100% is of .nav-right, not the bar,
   since the switcher sits beside it. Give .nav-right the full row too, so
   the links keep spreading the way they always did, and let the switcher
   wrap to its own line under them, right-aligned like it is everywhere
   else. With script the phone menu above takes over and the switcher sits
   at the right end of the panel's last row through the same margin. */
@media (max-width: 499px) {
  .nav-right { width: 100%; }
}
@media (max-width: 999px) {
  .lang-switcher { margin-left: auto; }
}

/* ---------- Colour theme switch ----------
   Two buttons in one pill: the same border, surface, radius and font size as
   the language switcher's summary, and the same height, so the header reads as
   one row of controls rather than two unrelated widgets.

   It sits in .nav-controls inside .nav-right, in normal flow, and wraps with
   everything else. It is deliberately not in a fixed height track and not
   absolutely positioned into the header's right edge: that is exactly what
   collided with the wrapped nav at phone widths on the Shopify shop. Under
   1000px with script, the phone menu holds it: the last row of the panel, this
   one flush left and the language switcher pushed flush right by its own
   margin-left: auto. Without script at 499px and under, .nav-right takes the
   whole row, .links take the row under the brand, and the two controls share
   the row below that the same way. If a long language name leaves them no
   room, they wrap onto separate rows; flex never lets them overlap. On 404 and
   gift, which have no header to join, this one is pinned to the top left, the
   one corner the floating language switcher does not use, so the two cannot
   meet at any width or in any language.

   Both themes come out of the same tokens: the pill is --surface, the pressed
   button is --bg with --gold-text on it, the same "this is the current one"
   signal the nav links and the language list already use. The pressed state
   changes colour only, never the font weight, so toggling shifts nothing. */
.theme-switch {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface);
}
.theme-switch-floating { position: fixed; top: 14px; left: 16px; z-index: 50; }
.theme-switch button {
  font: inherit; font-size: 0.82rem; line-height: 1.2; white-space: nowrap;
  padding: 7px 10px; border: none; border-radius: 999px;
  background: transparent; color: var(--muted); cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.theme-switch button:hover { color: var(--text); }
/* The inset ring carries the selected side in the light theme, where --bg on
   --surface is only a few units of difference; in dark it reads as the edge of
   the recess. No new colour, just --border again. */
.theme-switch button[aria-pressed="true"] {
  background: var(--bg); color: var(--gold-text);
  box-shadow: inset 0 0 0 1px var(--border);
}
.theme-switch button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }


/* ---------- Motion ---------- */

@keyframes rise-in {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes dot-breathe {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.45; transform: scale(0.82); }
}

/* The js class is added by site.js before the first paint; without it the
   reveal blocks stay visible, so the page never depends on the script. (The
   six site assets name each other by file name, never by path: their names
   carry a content hash, see site-tools/hash-assets.mjs.) */
.js .reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.6s ease, transform 0.6s ease; }
.js .reveal.in { opacity: 1; transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js .reveal { opacity: 1 !important; transform: none !important; }
}
