/* Hugentobler3D shared stylesheet.
 *
 * The palette, the page chrome (header, nav, footer), and the components that appear on more
 * than one page. Linked by every page before its own <style> block, so a page rule of equal
 * specificity always wins - page-specific CSS stays inline, next to the markup it styles.
 *
 * What lives here is what was byte-identical across pages before consolidation. Rules that
 * genuinely differ per page - h1 sizes, the lightbox dimensions, .buy-primary padding - were
 * deliberately left inline rather than reconciled into a compromise nobody chose.
 *
 * There is still no build step. This is a plain stylesheet served as a static file.
 */


/* ---------------------------------------------------------------------------
   Palette
   ---------------------------------------------------------------------------

   Every colour on this site is a token, defined here and redefined for dark mode below. No
   rule anywhere else knows which scheme is active, which is the only reason dark mode works
   at all - a hardcoded hex is invisible until someone opens the site at night.

   This block used to be copied into all twelve pages. By the time it was consolidated the
   five copies had already drifted into five different token sets: same values, but pages
   silently missing --glow, --etsy-fill, --scrim-ink. That is the drift the duplication was
   always going to produce, and it is why this file exists.

   Never put #fff on --accent. A light blue carries white text at 2:1. That is what
   --accent-ink is for: accent-filled controls take deep navy (6-8:1). --accent-dark is a
   ROLE, not a literal - darker than --accent in light mode, lighter in dark. */
:root {
  color-scheme: light dark;
  --field: #ffffff;
  --photo-bg: #d9d2c5;
  --ink: #20252a;
  --muted: #646c74;
  --paper: #f4f1eb;
  --cream: #fffdf8;
  --scrim-ink: #f4f1eb;
  --accent: #3f9fd4;
  --accent-hover: #3590c4;
  --accent-dark: #0f4c75;
  --accent-ink: #051724;
  --accent-ring: rgba(63, 159, 212, 0.32);
  --star: #1c6f9e;
  --etsy: #e65f24;
  --etsy-fill: #b84416;
  --etsy-ink: #ffffff;
  --line: #ddd6ca;
  --shadow: 0 20px 55px rgba(32, 37, 42, 0.12);
  --glow: 0 12px 30px rgba(63, 159, 212, 0.36);
  --glow-strong: 0 16px 38px rgba(63, 159, 212, 0.5);
}

/* Dark mode. Only the tokens are redefined; every rule in this file and in every page is
   written against them, so nothing below needs to know which scheme is showing.

   The relationships are preserved rather than the values: --cream still sits slightly above
   --paper, the accent brightens so it keeps its punch against a dark ground, and
   --accent-dark keeps its role - accent-coloured text - which on dark means lighter than
   --accent rather than darker. */
@media (prefers-color-scheme: dark) {
  :root {
    --ink: #ece6dc;
    --muted: #99a2ac;
    --paper: #15181c;
    --cream: #1e2228;
    --field: #23272e;
    --photo-bg: #242a31;
    --scrim-ink: #f4f1eb;
    --accent: #4aabd8;
    --accent-hover: #5cb8e2;
    --accent-dark: #a9dff5;
    --accent-ink: #06202f;
    --accent-ring: rgba(74, 171, 216, 0.4);
    --star: #8fd4f2;
    --etsy: #e3632b;
    --etsy-fill: #f9a06e;
    --etsy-ink: #2b1206;
    --line: #333941;
    --shadow: 0 20px 55px rgba(0, 0, 0, 0.5);
    --glow: 0 12px 30px rgba(74, 171, 216, 0.3);
    --glow-strong: 0 16px 38px rgba(74, 171, 216, 0.44);
  }
}

* { box-sizing: border-box; }

/* An author `display` on a class always beats the browser's own [hidden]{display:none},
   so .nav-cart and .cart-layout were both rendering while still marked hidden. Every
   toggled element on this site uses the attribute, so it is enforced once here. */

[hidden] { display: none !important; }

body {
  margin: 0;
  min-width: 320px;
  background: var(--paper);
  color: var(--ink);
  font-family: Georgia, 'Times New Roman', serif;
}

a { color: inherit; }

/* Links inside sentences. The About page's signature email set the house style and this is
   it, shared: muted rather than browser blue, underlined well clear of the descenders, and
   picking up the accent on hover so it is clearly a control and not just decorated text.
   Nav items, buy buttons, and product cards are links too, and none of them want this - they
   are styled where they live. Hence a class rather than a bare `a` rule, which would repaint
   every button on the site. `.site-footer p a` is carried here because the same "Leave
   feedback" link sits in all twelve footers and had no treatment at all: it inherited the
   footer's muted colour with no underline, so it read as plain text. */
.text-link,
.site-footer p a {
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  transition: color .2s ease;
}

.text-link:hover,
.site-footer p a:hover { color: var(--accent-dark); }

.site-header,
main,
.site-footer {
  width: min(1180px, calc(100% - 2.5rem));
  margin: 0 auto;
}

.site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.35rem 0;
}

.brand { display: inline-flex; align-items: center; }

.brand img { width: 155px; height: auto; }

/* The logo is a flat black silhouette produced by tools/make-mono-logo.py. Inverting it
   is enough to tint it for dark mode, and keeps the <img> and its alt text intact.
   0.93 rather than 1 lands on rgb(237,237,237), which sits with --ink instead of
   glaring pure white next to it. */

@media (prefers-color-scheme: dark) {
  .brand img { filter: invert(0.93); }
}

nav { display: flex; align-items: center; gap: 1.5rem; font: 600 0.8rem/1 'Segoe UI', sans-serif; }

nav a { text-decoration: none; }

nav a:hover { color: var(--accent-dark); }

nav a[href*="etsy.com"] { color: var(--etsy); }

/* Ships-to chip. The dialog it opens is built and styled by res/shop.js - one copy of a
   control that has to say the same thing on every page - but the chip itself is nav
   chrome, so it is styled here with the rest of the nav and cannot flash unstyled. */

.nav-region { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; }

.nav-region:hover { color: var(--accent-dark); }

.nav-flag { display: block; border: 1px solid var(--line); }

.nav-cart { display: inline-flex; align-items: center; gap: 0.4rem; }

.cart-count { display: grid; place-items: center; min-width: 1.35rem; height: 1.35rem; padding: 0 0.35rem; border-radius: 999px; background: var(--accent); color: var(--accent-ink); font-size: 0.7rem; }

.eyebrow { margin: 0 0 1.1rem; color: var(--accent-dark); font: 700 0.73rem/1.2 'Segoe UI', sans-serif; letter-spacing: 0.16em; text-transform: uppercase; }

.lightbox::backdrop { background: rgba(32, 37, 42, 0.85); }

.lightbox-close:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.buy-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); box-shadow: var(--glow-strong); transform: translateY(-2px); }

.buy-primary:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.buy-primary[disabled] { border-color: var(--line); background: var(--cream); color: var(--muted); box-shadow: none; cursor: default; }

.buy-primary[disabled]:hover { background: var(--cream); border-color: var(--line); transform: none; box-shadow: none; }

.buy-etsy {
  /* Always sits under Add to cart, so it carries its own separation. */
  margin-top: 0.6rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 1rem 1.1rem;
  border: 1px solid var(--etsy-fill);
  border-radius: 0;
  background: var(--etsy-fill);
  color: var(--etsy-ink);
  font: 700 0.92rem 'Segoe UI', sans-serif;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: filter .2s ease, transform .2s ease;
}

.buy-etsy:hover { filter: brightness(1.08); transform: translateY(-2px); }

.buy-etsy:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }

.buy-secondary:hover { color: var(--accent-dark); }

.testimonial { min-height: 215px; padding: 1.5rem; border: 1px solid var(--line); background: var(--cream); }

.testimonial cite { display: block; margin-top: 1.5rem; color: var(--muted); font: 600 0.75rem 'Segoe UI', sans-serif; font-style: normal; }

.testimonial a { display: inline-block; margin-top: 1rem; color: var(--accent-dark); font: 600 0.75rem 'Segoe UI', sans-serif; }

.review-stars { color: var(--star); font: 1rem 'Segoe UI', sans-serif; letter-spacing: 0.08em; }

.review-photo-button { display: block; width: 100%; padding: 0; margin: 0 0 1.25rem; border: 0; background: none; cursor: zoom-in; }

.review-photo-button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

.review-photo { display: block; width: 100%; height: 250px; object-fit: cover; }

.reviews-actions { margin-top: 2rem; text-align: center; }

.reviews-actions button { border: 1px solid var(--ink); padding: 0.8rem 1.2rem; background: transparent; color: var(--ink); cursor: pointer; font: 600 0.8rem 'Segoe UI', sans-serif; }

.reviews-actions button:hover { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

.reviews-actions button[disabled] { opacity: 0.55; cursor: default; }

.site-footer { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2rem; padding: 1.5rem 0 2rem; border-top: 1px solid var(--line); color: var(--muted); font: 0.78rem 'Segoe UI', sans-serif; }

.site-footer p { margin: 0; }

.footer-usa { text-align: center; }

/* Sits on its own row below the three footer columns. Etsy requires the notice to be
   displayed, not buried, so it is full width rather than squeezed in as a fourth column
   nobody would read. */

.footer-legal { flex-basis: 100%; margin-top: 1.1rem; font-size: 0.72rem; }

.eyebrow { margin: 0 0 1.2rem; color: var(--accent-dark); font: 700 0.73rem/1.2 'Segoe UI', sans-serif; letter-spacing: 0.16em; text-transform: uppercase; }

.nav-current { border-bottom: 2px solid var(--accent); padding-bottom: 0.45rem; }

/* Mirrored Etsy stock, said quietly.

   Set at the same size and weight as the "View details" link it sits beside, in --muted,
   with no dot and no colour coding. An earlier version used a coloured bullet per state; on
   a shop whose Etsy quantities are all single digits that put an urgent-looking marker on
   nearly every product at once, which reads as manufactured scarcity rather than
   information. The count is worth stating and is not worth shouting. */
.stock-note { margin: 0; color: var(--muted); font: 600 0.78rem 'Segoe UI', sans-serif; }
