/* Hyve Ink — the public site.
   ---------------------------------------------------------------------------
   The landing page, pricing and contact. Tokens come from styles.css; nothing
   here defines a colour of its own, so both themes stay correct by construction.

   Layout is flex/grid with gap throughout rather than per-element margins —
   collapsing margins are how a page ends up with spacing that looks right on one
   screen and wrong on the next. */

.site * { box-sizing: border-box; }

.site {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--body);
  font-size: 16.5px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.site h1, .site h2, .site h3, .site h4 {
  font-family: var(--display);
  font-weight: 700;
  letter-spacing: -.022em;
  line-height: 1.08;
  margin: 0;
  text-wrap: balance;
}
/* Tight tracking is a large-type correction. At 17-19px it just closes the counters up. */
.site h3, .site h4 { letter-spacing: -.008em; }

.site a { color: inherit; }
.site img { display: block; max-width: 100%; }
/* The focus ring is defined once, unscoped, in styles.css — the order flow needs it too. */

.wrap { width: 100%; max-width: var(--page); margin: 0 auto; padding: 0 24px; }

/* ============================================================ header */

.hdr {
  position: sticky; top: 0; z-index: var(--layer-sticky);
  background: color-mix(in srgb, var(--bg) 86%, transparent);
  backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid var(--line);
}
.hdr .wrap { display: flex; align-items: center; gap: 12px; height: 68px; }

.brand { display: flex; align-items: center; gap: 11px; text-decoration: none; flex-shrink: 0; }
/* The shop's own mark (img/hyve-logo.png, 130 x 120 for a 33 x 30 box). */
.brand img { width: 33px; height: 30px; display: block; }
.brand .wordmark {
  font-family: var(--display); font-weight: 800; font-size: 20px;
  letter-spacing: -.03em; line-height: 1;
}
.brand .wordmark em { font-style: normal; color: var(--accent-ink); }

.nav { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.nav a {
  text-decoration: none; color: var(--muted); font-size: var(--fs-sm); font-weight: 600;
  padding: 8px 13px; border-radius: var(--r-sm); white-space: nowrap;
  transition: color .15s, background .15s;
}
.nav a:hover { color: var(--ink); background: var(--panel-2); }
.nav a[aria-current="page"] { color: var(--ink); }

/* The order button is the point of the whole header, so it does not look like the
   other links. Same treatment as the hero's primary action, deliberately. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-family: var(--display); font-weight: 700; font-size: 15px; letter-spacing: -.01em;
  padding: 12px 22px; border-radius: var(--r-md); border: 1px solid transparent;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: transform .12s ease, box-shadow .15s ease, background .15s;
}
.btn:active { transform: translateY(1px); }
/* `.site a { color: inherit }` outranks a bare .btn-primary, so every primary button that
   is a link drew its label in --ink: near-black on the fill, 4.08:1. Named as a link too,
   the label is the white the token always said: 5.15:1. */
.btn-primary, .site a.btn-primary { background: var(--accent-fill); color: var(--on-accent); box-shadow: var(--shadow-sm); }
.btn-primary:hover { background: var(--accent); box-shadow: var(--shadow-md); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--accent); background: var(--panel); }
.btn-lg { font-size: 17px; padding: 16px 30px; border-radius: var(--r-md); }

.hdr .btn { margin-left: 8px; }

/* Theme toggle. Three states are real, but a control with three positions confuses
   people — this flips light/dark and stops stamping nothing, which is fine because
   touching it IS an explicit choice. */
.theme-btn {
  display: grid; place-items: center; width: 38px; height: 38px; flex-shrink: 0;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: transparent; color: var(--muted); cursor: pointer;
}
.theme-btn:hover { color: var(--ink); border-color: var(--accent); }
.theme-btn svg { width: 17px; height: 17px; }
:root:not([data-theme="dark"]) .theme-btn .moon { display: none; }
:root[data-theme="dark"] .theme-btn .sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .theme-btn .sun { display: none; }
  :root:not([data-theme]) .theme-btn .moon { display: block; }
}

/* Below 780px the links used to be display:none with nothing in their place, so a phone
   — which is how most of this shop's customers arrive — got no navigation at all. They
   move to a row of their own under the logo, and wrap onto a second when they do not
   fit. No JavaScript, no menu to open, every destination one tap away and in plain sight.

   They used to scroll sideways instead, with the scrollbar hidden — and with the row 48px
   narrower than the screen, because the negative margins pulled it left without widening
   it. At 400px that cut "Your designs" off at "Your d" and hid "Account" altogether, with
   nothing on screen to say there was more to swipe to. */
@media (max-width: 780px) {
  /* Two sticky rows would eat 17% of a 640px-tall screen. */
  .hdr { position: static; }
  .hdr .wrap {
    flex-wrap: wrap; height: auto; min-height: 60px; gap: 8px; padding-block: 9px 0;
  }
  .brand { margin-right: auto; }

  /* Edge to edge, so the rule above the links runs the width of the screen: out past the
     .wrap's 24px padding on both sides, and wider by the same, then padded back in so the
     first link's text lines up with the logo. */
  .nav {
    order: 5; flex-wrap: wrap; gap: 0 4px;
    width: calc(100% + 48px); margin: 8px -24px 0; padding: 0 14px;
    border-top: 1px solid var(--line);
  }
  .nav a { padding: 11px 10px; }
  .nav a[aria-current="page"] { box-shadow: inset 0 -2px 0 var(--accent-fill); }

  .hdr .btn { margin-left: 0; }
  /* No room for two buttons beside the logo. The hero's own "Design your stuff" is the
     next thing on the screen, so Sign in keeps the top-right corner. */
  .hdr .hdr-cta { display: none; }
  .btn { padding: 10px 16px; font-size: 14px; }
}

/* ============================================================ hero */

.hero { padding: clamp(56px, 9vw, 108px) 0 clamp(48px, 7vw, 88px); position: relative; overflow: hidden; }
.hero .wrap { display: grid; gap: 56px; align-items: center; }
@media (min-width: 940px) { .hero .wrap { grid-template-columns: 1.05fr .95fr; } }

.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 11.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--accent-ink);
  background: var(--accent-soft); border-radius: 100px; padding: 6px 14px;
  margin-bottom: 20px;
}

/* Five elements previously sat 26/26/26/36/34px apart — near enough identical that
   nothing grouped with anything. The gaps now step, and the assurances sit under a rule
   so they read as a footnote to the block rather than a fourth peer. */
.hero h1 { font-size: clamp(34px, 8vw, 78px); font-weight: 800; letter-spacing: -.038em; }
.hero h1 .rule {
  display: block; width: 68px; height: 5px; border-radius: 3px;
  background: var(--accent-fill); margin: 22px 0 0;
}
.hero .sell {
  font-size: clamp(17px, 2.1vw, 20px); color: var(--muted);
  max-width: 46ch; margin: 20px 0 0;
}
.hero .actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }

.hero .assurances {
  display: flex; flex-wrap: wrap; gap: 8px 26px; padding: 22px 0 0;
  margin: 30px 0 0; border-top: 1px solid var(--line);
  list-style: none; font-size: var(--fs-xs); color: var(--muted);
}
.hero .assurances li { display: flex; align-items: center; gap: 8px; }
.hero .assurances svg { width: 15px; height: 15px; color: var(--accent-ink); flex-shrink: 0; }

/* The hero's image is the product: the real proof renderer, on SanMar's own photo of a
   real garment, with a print area to scale. It was once a hand-drawn shirt filled --panel
   on a --bg ground — 1.03 contrast, an invisible white ghost — captioned "11 in" against
   a print box that was 77% of the garment width, which is about 16". A picture that
   misstates scale is the one thing this site cannot afford on its front page. */
.hero-art { display: grid; justify-items: center; align-content: center; gap: 16px; }
/* The renderer's host. Explicit full width, or `justify-items: center` shrink-wraps it
   and the carousel's `width: 100%` has nothing to resolve against. */
.hero-art > div { width: 100%; display: flex; justify-content: center; }

.hero-carousel { width: 100%; max-width: 420px; display: grid; justify-items: center; gap: 12px; }
/* One fixed-ratio stage with every slide stacked in it, so a hoodie (taller, for its
   hood) and a tee cross-fade without the page moving under them. */
.hero-stage { position: relative; width: 100%; aspect-ratio: 5 / 6; }
.hero-slide {
  position: absolute; inset: 0; display: block;
  opacity: 0; visibility: hidden;
  transition: opacity .6s ease, visibility 0s linear .6s;
}
.hero-slide.is-on { opacity: 1; visibility: visible; transition: opacity .6s ease, visibility 0s; }
.hero-slide svg {
  width: 100%; height: 100%;
  filter: drop-shadow(0 24px 40px var(--shadow-art));
}
.hero-garment {
  font-size: var(--fs-sm); font-weight: 600; color: var(--ink); text-decoration: none;
}
.hero-garment:hover { text-decoration: underline; }
.hero-dots { display: flex; gap: 2px; }
/* A 24px target around an 8px dot. */
.hero-dot {
  width: 24px; height: 24px; padding: 0; border: 0; background: none; cursor: pointer;
  display: grid; place-items: center;
}
.hero-dot::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--line); transition: background .2s, transform .2s;
}
.hero-dot:hover::before { background: var(--muted); }
.hero-dot[aria-current="true"]::before { background: var(--accent-ink); transform: scale(1.25); }
.hero-art .note {
  margin: 0; max-width: 36ch; text-align: center;
  font-size: var(--fs-xs); color: var(--muted);
}

/* ============================================================ sections */

.section { padding: clamp(56px, 8vw, 96px) 0; }
.section--tint { background: var(--panel-2); border-block: 1px solid var(--line); }
/* Two untinted sections in a row doubled their padding into ~190px of dead field. Both
   sides have to be untinted — collapsing the gap after a tinted band would butt the next
   section straight against its border. */
.section:not(.section--tint) + .section:not(.section--tint) { padding-top: 0; }

.section-head { max-width: 62ch; margin-bottom: 42px; }
.section-head h1 { font-size: clamp(34px, 5.2vw, 54px); letter-spacing: -.032em; }
.section-head h2 { font-size: clamp(28px, 4vw, 42px); }
.section-head p { color: var(--muted); margin: 16px 0 0; font-size: var(--fs-md); }

/* A section heading one level down. This was an inline font-size clamp repeated five
   times across pricing.html and contact.html. */
.section-head--sub { margin-bottom: 28px; }
.section-head--sub h2 { font-size: clamp(22px, 3vw, 30px); }

/* A footnote under a block, rather than a lede above one. */
.section-note {
  color: var(--muted); font-size: var(--fs-xs); margin-top: 16px; max-width: 62ch;
}
.section-head .kicker, .pd-info .kicker {
  font-family: var(--mono); font-size: 11.5px; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--accent-ink); display: block; margin-bottom: 14px;
}

/* ============================================================ showcase */

/* A horizontal rail, because past work is browsed rather than read. Scrolls inside
   itself so the page body never scrolls sideways. */
/* The rail bleeds to the viewport edge deliberately, from inside a .wrap, so its first
   card lines up with the section heading above it. It used to sit outside .wrap entirely
   and the JS replaced the wrapper, so the empty state rendered edge-to-edge with no
   gutter at all. */
.showcase {
  overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
  margin-inline: -24px; padding-inline: 24px;
}
.showcase-track { display: flex; gap: 20px; padding: 4px 0 24px; width: max-content; }
.showcase-track > * { scroll-snap-align: start; }

.work {
  width: min(340px, 78vw); background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-sm);
  transition: transform .18s ease, box-shadow .18s ease;
}
.work:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); }
.work .shot { aspect-ratio: 4 / 3; background: var(--panel-2); display: grid; place-items: center; }
.work .shot img { width: 100%; height: 100%; object-fit: cover; }
.work .meta { padding: 16px 18px 18px; }
.work .meta h3 { font-size: 17px; }
.work .meta p { margin: 6px 0 0; color: var(--muted); font-size: var(--fs-xs); }

/* Nothing fake ever renders. Until the shop supplies real job photos, the rail says
   so plainly rather than showing invented work — see web/showcase.json. */
.showcase-empty {
  border: 1.5px dashed var(--line); border-radius: var(--r-lg);
  padding: 46px 28px; text-align: center; color: var(--muted); background: var(--panel);
}
.showcase-empty h3 { font-size: 19px; color: var(--ink); }
.showcase-empty p { margin: 10px auto 0; max-width: 52ch; font-size: var(--fs-sm); }

/* ============================================================ services */

.grid-3 { display: grid; gap: 20px; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr)); }

.card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 28px 26px; box-shadow: var(--shadow-sm);
}
.card .icon {
  width: 42px; height: 42px; border-radius: var(--r-md); display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent-ink); margin-bottom: 18px;
}
.card .icon svg { width: 21px; height: 21px; }
.card h3 { font-size: 19px; }
.card p { color: var(--muted); margin: 10px 0 0; font-size: var(--fs-sm); }

/* ============================================================ call to action */

/* Inverted against the page. This used --ink as the background, which works in light and
   turns into a full-width blinding white slab in dark — so it gets its own pair of
   tokens instead of borrowing the text colour. */
.cta {
  background: var(--cta-bg); color: var(--cta-ink); border-radius: var(--r-xl);
  border: 1px solid color-mix(in srgb, var(--accent) 26%, transparent);
  padding: clamp(40px, 6vw, 68px); text-align: center; box-shadow: var(--shadow-lg);
  position: relative; overflow: hidden;
}
.cta h2 { font-size: clamp(28px, 4.4vw, 46px); color: var(--cta-ink); }
.cta p {
  max-width: 52ch; margin: 18px auto 0; font-size: var(--fs-md);
  color: color-mix(in srgb, var(--cta-ink) 78%, transparent);
}
.cta .actions { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; margin-top: 32px; }
.cta .btn-ghost { color: var(--cta-ink); border-color: var(--cta-edge); }
.cta .btn-ghost:hover { background: color-mix(in srgb, var(--cta-ink) 12%, transparent); border-color: var(--cta-ink); }

/* ============================================================ contact */

.contacts { display: grid; gap: 18px; grid-template-columns: repeat(auto-fit, minmax(268px, 1fr)); }
.contact-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 24px; display: flex; flex-direction: column; gap: 8px;
}
.contact-card .who { font-family: var(--display); font-weight: 700; font-size: 17px; }
.contact-card .role { color: var(--muted); font-size: var(--fs-xs); }
.contact-card a {
  font-family: var(--mono); font-size: var(--fs-xs); color: var(--accent-ink);
  text-decoration: none; overflow-wrap: anywhere; margin-top: auto; padding-top: 8px;
}
.contact-card a:hover { text-decoration: underline; }

/* ============================================================ pricing */

.price-table { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--panel); }
.price-table table { border-collapse: collapse; width: 100%; min-width: 620px; font-size: 15px; }
.price-table th, .price-table td { padding: 12px 16px; text-align: right; white-space: nowrap; }
.price-table th:first-child, .price-table td:first-child { text-align: left; }
.price-table thead th {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; border-bottom: 1.5px solid var(--line);
  background: var(--panel);
}
.price-table tbody td { border-bottom: 1px solid var(--line-soft); font-variant-numeric: tabular-nums; font-family: var(--mono); }
.price-table tbody td:first-child { font-family: var(--body); font-weight: 600; }
.price-table tbody tr:last-child td { border-bottom: 0; }
.price-table tbody tr:hover { background: var(--panel-2); }
.price-table .none { color: var(--muted); font-family: var(--body); font-style: italic; font-size: 13.5px; }

.fees { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.fee {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-md); padding: 20px 22px;
}
.fee .amt { font-family: var(--display); font-weight: 800; font-size: 30px; letter-spacing: -.03em; }
.fee .what { font-size: var(--fs-xs); color: var(--muted); margin-top: 4px; }

.note-band {
  background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--warn-ink);
  border-radius: var(--r-md); padding: 16px 20px; font-size: 15px;
}
.note-band strong { font-weight: 700; }

/* ============================================================ footer */

.ftr { border-top: 1px solid var(--line); padding: 48px 0 40px; margin-top: 0; background: var(--panel-2); }
.ftr .wrap { display: flex; flex-wrap: wrap; gap: 28px 48px; align-items: flex-start; }
.ftr .col { display: grid; gap: 9px; align-content: start; }
.ftr .col h4 {
  font-family: var(--mono); font-size: 11px; letter-spacing: .13em; text-transform: uppercase;
  color: var(--muted); font-weight: 600; margin-bottom: 3px;
}
/* Replaces an inline style repeated six times across the three public pages. */
.ftr .col span { color: var(--muted); font-size: var(--fs-xs); }
.ftr a { color: var(--muted); text-decoration: none; font-size: var(--fs-xs); }
.ftr a:hover { color: var(--ink); }
.ftr .legal { width: 100%; border-top: 1px solid var(--line); padding-top: 22px; color: var(--muted); font-size: 13px; }

/* ============================================================ catalogue (/catalog) */

.cat-filters { display: flex; flex-wrap: wrap; gap: 10px 14px; align-items: center; margin-bottom: 22px; }
.cat-search { flex: 1 1 260px; }
.cat-search input, .cat-brand select {
  width: 100%; font: inherit; font-size: 15px; color: var(--ink); background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--r-md); padding: 10px 13px;
}
.cat-search input:focus-visible, .cat-brand select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cat-brand { flex: 0 1 240px; }
.cat-chips { display: flex; flex-wrap: wrap; gap: 6px; width: 100%; }
.cat-filters .chip, .pd .chip {
  font: inherit; font-size: 13px; font-weight: 600; line-height: 1; color: var(--muted);
  background: var(--panel); border: 1px solid var(--line); border-radius: 999px;
  padding: 8px 12px; cursor: pointer; text-decoration: none; display: inline-block;
}
.cat-filters .chip:hover, .pd .chip:hover { color: var(--ink); border-color: var(--accent); }
.cat-filters .chip[aria-pressed='true'], .pd .chip[aria-pressed='true'] {
  background: var(--accent-fill); border-color: var(--accent-fill); color: var(--on-accent);
}
.cat-toggle { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--muted); }
.cat-toggle input { margin: 0; }
.cat-count, .cat-status { color: var(--muted); font-size: var(--fs-sm); margin: 0 0 14px; }
.cat-status a { color: var(--accent-ink); }
.cat-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.cat-card {
  display: flex; flex-direction: column; gap: 6px; text-decoration: none; color: var(--ink);
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 12px; box-shadow: var(--shadow-sm);
}
.cat-card:hover { border-color: var(--accent); }
.cat-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cat-thumb {
  position: relative; display: grid; place-items: center; aspect-ratio: 4 / 5; width: 100%;
  border-radius: var(--r-md); background: #FFFFFF; border: 1px solid var(--line-soft); overflow: hidden;
}
.cat-thumb-code { font-family: var(--mono); font-size: 13px; color: #8E95A3; letter-spacing: .06em; }
.cat-thumb-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.cat-card-title { font-weight: 600; font-size: 14.5px; line-height: 1.35; margin-top: 4px; }
.cat-card-meta { color: var(--muted); font-size: 12.5px; }
.cat-badge {
  align-self: flex-start; font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); border: 1px dashed var(--line); border-radius: 999px; padding: 3px 8px;
}
.cat-more { margin: 22px 0 0; text-align: center; }
.cat-back { margin: 0 0 18px; font-size: 14px; }
.cat-back a { color: var(--muted); text-decoration: none; }
.cat-back a:hover { color: var(--ink); }

/* ============================================================ one garment (/product) */

.pd { display: grid; gap: 32px 48px; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); align-items: start; }
@media (max-width: 760px) { .pd { grid-template-columns: 1fr; } }
.pd-visual { display: grid; gap: 10px; }
.pd-photo {
  display: grid; place-items: center; aspect-ratio: 2 / 3; width: 100%;
  background: #FFFFFF; border: 1px solid var(--line-soft); border-radius: var(--r-lg); overflow: hidden;
}
.pd-photo-img { width: 100%; height: 100%; object-fit: contain; }
.pd-photo-none { display: grid; gap: 8px; justify-items: center; color: #8E95A3; font-size: 14px; }
.pd-sides { display: flex; gap: 6px; }
.pd-info h1 { margin: 6px 0 8px; font-size: clamp(24px, 3.2vw, 34px); }
.pd-meta { color: var(--muted); font-family: var(--mono); font-size: 13px; margin: 0 0 12px; }
.pd-cats { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 16px; }
.pd-description { color: var(--ink-soft); font-size: var(--fs-sm); margin: 0 0 16px; max-width: 60ch; }
.pd-price-note { color: var(--muted); font-size: var(--fs-sm); margin: 0 0 20px; }
.pd-hand {
  background: var(--warn-bg); border: 1px solid var(--warn-line); color: var(--warn-ink);
  border-radius: var(--r-md); padding: 12px 16px; font-size: 14.5px; margin: 0 0 20px;
}
.pd-h2 { font-size: 15px; margin: 0 0 6px; }
.pd-chosen { display: flex; align-items: center; gap: 10px; margin: 0 0 10px; font-size: 15px; }
.pd-colours { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 10px; }
.pd-swatch {
  display: grid; justify-items: center; gap: 5px; width: 84px; padding: 6px 4px; font: inherit;
  background: transparent; border: 1px solid transparent; border-radius: var(--r-md); cursor: pointer; color: var(--muted);
}
.pd-swatch:hover { border-color: var(--line); background: var(--panel); }
.pd-swatch[aria-pressed='true'] { border-color: var(--accent-fill); background: var(--panel); color: var(--ink); }
.pd-swatch-well {
  width: 40px; height: 40px; border-radius: 50%; overflow: hidden; background: var(--panel-2);
  border: 1px solid var(--line); display: block;
}
.pd-swatch-hand .pd-swatch-well { border-style: dashed; }
.pd-swatch-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pd-swatch-name { font-size: 11px; line-height: 1.2; text-align: center; }
.pd-hint, .pd-sizes { color: var(--muted); font-size: 13.5px; margin: 0 0 8px; }
.pd-sizes { color: var(--ink-soft); font-size: var(--fs-sm); margin-top: 14px; }
.pd-actions { margin: 22px 0 0; }

/* ============================================================ home: services (PLAN 4.1) */

/* The "what we do" cards on the home page: six equal cards in one grid, in two labelled
   groups. The group titles are auto rows spanning the grid; every card row is 1fr, and in
   an auto-height grid 1fr rows all size to the tallest, so every card is the same height
   whichever group it is in. */
.service-group-title {
  grid-column: 1 / -1;
  font-family: var(--mono); font-size: 12px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted); margin: 0;
  padding-bottom: 10px; border-bottom: 1px solid var(--line);
}
.service-group-title ~ .service-group-title { margin-top: 20px; }
.service-grid {
  display: grid; gap: 20px; grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: auto 1fr auto 1fr;
}
.service-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 24px; box-shadow: var(--shadow-sm); display: flex; flex-direction: column;
}
.service-card-head { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.service-icon {
  flex: none; width: 44px; height: 44px; border-radius: var(--r-md); display: grid;
  place-items: center; background: var(--accent-soft); color: var(--accent-ink);
}
.service-icon svg { width: 22px; height: 22px; }
.service-card h4 { font-size: 19px; margin: 0; }
.service-card p { color: var(--muted); margin: 0; font-size: var(--fs-sm); }

@media (max-width: 860px) {
  /* One column rather than two: three cards in two columns leaves an orphan. */
  .service-grid { grid-template-columns: 1fr; grid-template-rows: none; }
}

/* ============================================================ address (PLAN 2.3) */

.ftr .ftr-addr { font-style: normal; color: var(--muted); font-size: var(--fs-xs); line-height: 1.55; }
.visit {
  margin-top: 18px; background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 24px; display: flex; flex-wrap: wrap;
  align-items: center; justify-content: space-between; gap: 16px 24px;
}
.visit-title { font-size: 17px; margin: 0 0 6px; }
.visit-addr { font-style: normal; color: var(--muted); font-size: var(--fs-sm); line-height: 1.55; }

/* The paid page's "What you paid", drawn only when the order carried sales tax (web/paid.js). */
.paid-total[hidden] { display: none; }
.paid-row { display: flex; justify-content: space-between; gap: 12px; margin: 6px 0 0; font-variant-numeric: tabular-nums; }
