/* ==========================================================================
   THE LITTLE NEST · SHARED STYLESHEET
   Brand Guide v1.0. Presentation only: no cart, no checkout, no auth.

   If Zoho Commerce's Edit Code will not host a static asset, paste the whole
   of this file into a <style> block in each page's <head>. Nothing here
   depends on being an external file.
   ========================================================================== */

:root {
  /* neutrals */
  --shiplap:    #FBF8F2;
  --paper:      #FFFCF6;
  --cream:      #F6F2EA;
  --ink:        #1C1B17;

  /* structural greys */
  --grey:       #6b6a64;
  --grey-soft:  #d6d2c8;
  --grey-line:  #e6e1d6;

  /* accents · sparingly. Terracotta is promo-only (freight upsell). */
  --sage:       #5C6648;
  --terracotta: #C97A66;

  --serif: "Cormorant Garamond", "Times New Roman", serif;
  --caps:  "Julius Sans One", "Helvetica Neue", Arial, sans-serif;
  --body:  "Poppins", "Helvetica Neue", Arial, sans-serif;
  --mono:  ui-monospace, SFMono-Regular, Menlo, monospace;

  --container: 1440px;
  --pad: 56px;
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--shiplap);
  color: var(--ink);
  font-family: var(--body);
  font-size: 14px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, h4 { font-weight: 400; margin: 0; }
p { margin: 0; }
ul { list-style: none; margin: 0; padding: 0; }
::selection { background: var(--ink); color: var(--paper); }

:where(a, button, input, textarea):focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding-inline: var(--pad);
}

.serif { font-family: var(--serif); }
.caps  { font-family: var(--caps); text-transform: uppercase; letter-spacing: 0.26em; }
.mono  { font-family: var(--mono); }

.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--paper);
  padding: 12px 20px; z-index: 100;
  font-family: var(--caps); font-size: 11px; letter-spacing: 0.22em;
}
.skip:focus { left: 16px; top: 16px; }

/* ── Eyebrow ─────────────────────────────────────────────────────────── */
.eyebrow {
  display: flex; align-items: center; gap: 14px;
  color: var(--grey);
  font-family: var(--caps);
  font-size: 11px; letter-spacing: 0.28em; text-transform: uppercase;
}
.eyebrow::before {
  content: ""; width: 6px; height: 6px;
  background: var(--ink); flex: none;
}
.eyebrow.on-ink { color: rgba(255,255,255,0.6); }
.eyebrow.on-ink::before { background: var(--paper); }

/* ── Buttons ─────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 12px;
  font-family: var(--caps);
  font-size: 12px; letter-spacing: 0.22em; text-transform: uppercase;
  padding: 20px 36px;
  border: 1px solid #000;
  background: var(--ink); color: var(--paper);
  cursor: pointer;
  transition: background 180ms ease, color 180ms ease;
}
.btn:hover { background: var(--paper); color: var(--ink); }

.btn--ghost { background: transparent; color: var(--ink); }
.btn--ghost:hover { background: var(--ink); color: var(--paper); }

/* on the ink panel, the solid button inverts to paper */
.btn--onink {
  background: var(--paper); color: var(--ink); border-color: var(--paper);
}
.btn--onink:hover { background: transparent; color: var(--paper); }

.ulink {
  font-family: var(--caps);
  font-size: 11px; letter-spacing: 0.26em; text-transform: uppercase;
  padding-bottom: 4px;
  border-bottom: 1px solid #000;
  white-space: nowrap;
}

/* ── Announcement bar ────────────────────────────────────────────────
   Declarative facts only · the voice rules forbid CTA chatter. Sits above
   the sticky header so it scrolls away rather than eating viewport. */
.announce {
  background: var(--ink);
  color: var(--paper);
  text-align: center;
  padding-block: 10px;
}
.announce p {
  font-family: var(--caps);
  font-size: 10px; letter-spacing: 0.24em; text-transform: uppercase;
  color: rgba(255,255,255,0.82);
}

/* ── Trade / bulk band ───────────────────────────────────────────────
   The single biggest differentiator against a general retailer: most of
   this catalogue is bought by people fitting out rooms, not one bed. */
.trade {
  background: var(--cream);
  border-block: 1px solid var(--grey-line);
  padding-block: 72px;
}
.trade__inner {
  display: grid; grid-template-columns: 1.1fr 1fr;
  gap: 80px; align-items: center;
}
.trade h3 {
  font-family: var(--serif);
  font-size: clamp(32px, 3.8vw, 56px);
  line-height: 1.0; letter-spacing: -0.02em;
  margin-top: 20px;
}
.trade h3 em { font-style: italic; font-weight: 300; color: var(--grey); }
.trade p { margin-top: 22px; color: var(--grey); font-size: 15px; line-height: 1.7; max-width: 480px; }
.trade__cta { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; }
.trade__cta .note { font-size: 12px; color: var(--grey); }

/* ── Header ──────────────────────────────────────────────────────────── */
.header {
  position: sticky; top: 0; z-index: 30;
  background: rgba(251, 248, 242, 0.86);
  backdrop-filter: saturate(140%) blur(8px);
  -webkit-backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--grey-line);
}
.header__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 32px;
  padding-block: 18px;
}
.nav { display: flex; gap: 28px; align-items: center; }
.nav a {
  font-family: var(--caps);
  font-size: 11px; letter-spacing: 0.26em; text-transform: uppercase;
  padding-bottom: 4px;
  border-bottom: 1px solid transparent;
}
.nav a:hover, .nav a[aria-current="page"] { border-bottom-color: #000; }

/* The real lockup, hosted 14 Aug 2026. Two crops of one artwork:
   `logo-stack.png`  "THE LITTLE / NEST", no tagline  -> header
   `logo-lockup.png` all three lines                  -> footer
   The tagline is dropped in the header because at 44px tall it renders about
   4px high, which is a smudge rather than words. Both are ink on transparent;
   every surface the logo sits on is light (--shiplap header, --cream footer),
   so there is no inverted variant in play. Height is set and width follows, so
   the intrinsic width/height on the tag still reserves the right box. */
.wordmark { display: block; height: 44px; width: auto; }
.wordmark--foot { height: 82px; }
.wordmark--inv { filter: invert(1); }

/* Kept as the fallback the site shipped with. Nothing uses it now, but the
   rules cost nothing and a page that loses its <img> should not lose its
   name. See README §Assets. */
.wordmark-text { display: block; line-height: 1; }
.wordmark-text b {
  display: block;
  font-family: var(--caps);
  font-size: 17px; letter-spacing: 0.30em; font-weight: 400;
}
.wordmark-text i {
  display: block;
  font-family: var(--serif); font-style: italic;
  font-size: 13px; color: var(--grey); letter-spacing: 0.02em;
  margin-top: 6px;
}
.wordmark-text--lg b { font-size: 24px; }
.wordmark-text--lg i { font-size: 16px; }

.header__actions { display: flex; gap: 16px; align-items: center; justify-content: flex-end; }
/* Sign In + Nest as ONE unit. See the markup note: below 1100px
   `.header__actions` becomes `display: contents` and this wrapper is what
   keeps the pair together in column 3 instead of fighting for one cell. */
.header__btns { display: flex; gap: 16px; align-items: center; }
.account {
  font-family: var(--caps);
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  padding: 8px 14px;
  border: 1px solid var(--grey-line);
  background: transparent; color: var(--ink);
  transition: border-color 180ms ease;
}
.account:hover { border-color: var(--ink); }

.cart {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--caps);
  font-size: 11px; letter-spacing: 0.26em; text-transform: uppercase;
  padding: 10px 18px;
  border: 1px solid #000;
  background: var(--ink); color: var(--paper);
}
.cart__count {
  min-width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--paper); color: var(--ink);
  font-family: var(--body); font-size: 11px; font-weight: 500; letter-spacing: 0;
}
.nav-toggle { display: none; }

/* ── Image slots ──────────────────────────────────────────────────────
   `.ph` is the striped design-phase placeholder. Add `has-img` and drop an
   <img> inside it and the stripes, dashed inset and caption all disappear and
   the image fills the slot at the slot's own aspect ratio. That way a slot can
   be filled or emptied without touching layout. Added 5 Aug 2026.
   ------------------------------------------------------------------------ */
.ph {
  position: relative; width: 100%;
  background: repeating-linear-gradient(45deg, #f3f3f3 0 8px, #ececec 8px 16px);
  border: 1px solid var(--grey-line);
  overflow: hidden;
}
.ph::before {
  content: ""; position: absolute; inset: 14px;
  border: 1px dashed var(--grey-soft); pointer-events: none;
}
.ph__cap {
  position: absolute; left: 22px; bottom: 18px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--grey);
  background: var(--paper); padding: 4px 8px;
  border: 1px solid var(--grey-line);
}
/* Filled image slot · see the note above .ph.
   TWO shapes are supported and both must work:
     1. a bare <img> · the homepage lifestyle shots
     2. <picture><source ...><img></picture> · product imagery, which needs
        AVIF/WebP negotiation (build-shop-pages.py img_markup)
   The rule was `> img` only, a DIRECT child selector. Once product images
   arrived wrapped in <picture> the image was no longer a direct child, so it
   would have been left unpositioned and the 4:5 box would have collapsed · on the shop grid, 173 times. Widened 12 Aug 2026. */
.ph.has-img { background: none; border-color: var(--grey-line); }
.ph.has-img::before { content: none; }
.ph.has-img > img,
.ph.has-img > picture {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
}
.ph.has-img img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.ph.has-img > .ph__cap { display: none; }

/* HOVER ZOOM ON PHOTOGRAPHY, SITE-WIDE. Cazsper, 11 Sep 2026: he liked the
   effect the shop category tiles already had and asked for it on every photo.
   Deliberately the SAME 1.04 and the SAME 600ms curve as .shop-cat in shop.css,
   so the site reads as one gesture rather than two that nearly match.

   `.ph` already sets overflow:hidden. That is what clips the zoom, and it is
   why this belongs on .ph rather than on the images themselves.

   WHY THE SELECTOR IS A CLASS AND NOT A LIST OF PAGES: most photography on this
   site does not exist at build time. shop.js builds the grid tiles client side
   and the edge injects CMS photographs, and both add `has-img` along with the
   image. A rule on the class therefore covers every photo that ever appears,
   including products added long after this was written.

   THE LOGO IS DELIBERATELY EXCLUDED. It is `.wordmark` in the header and the
   footer, it is never inside `.ph`, and a wordmark that moves on hover reads as
   a fault rather than as polish.

   Four selectors because a photo is hovered in four different ways here: on its
   own (the product page image and the editorial pairs), inside a link (shop
   tiles, related products), inside `.card` (an <article> on the homepage whose
   anchor is a child, so `a:hover` alone would miss it when the cursor is on the
   card's text), and inside `.shop-tile`.

   Guarded on prefers-reduced-motion, matching .prod-thumb in shop.css. With
   reduced motion the photograph simply does not move. */
@media (prefers-reduced-motion: no-preference) {
  .ph.has-img img {
    transition: transform 600ms cubic-bezier(.2,.6,.2,1);
  }
  .ph.has-img:hover img,
  a:hover .ph.has-img img,
  .card:hover .ph.has-img img,
  .shop-tile:hover .ph.has-img img {
    transform: scale(1.04);
  }
}

/* Ratio utilities. WHICH ONE GOES WHERE WAS DECIDED BY PATRICK ON THE CALL OF
   17 Aug 2026, and the rule is short enough to keep here:
     · r-3-2  the homepage hero at the very top. "Three to two at the top."
              He reversed himself onto this mid-call and then settled: "Just
              keep it as it is." DO NOT CHANGE IT.
     · r-2-3  CATEGORY imagery, everywhere it appears. He wanted these
              "a little bit skinnier" so they line up with the artwork already
              produced at 2:3.
     · r-1-1  PRODUCT imagery, everywhere it appears, including the homepage
              featured-product block. "Product photos, one to one."
     · r-3-4  the homepage image strip. Editorial, never discussed, left alone.
   `.r-4-5` was the old product and category ratio. It is now used by nothing
   and has been REMOVED rather than left sitting here as dead CSS waiting to be
   reintroduced by accident. If a 4:5 slot is ever wanted again, add it back
   deliberately. */
.r-3-2 { aspect-ratio: 3 / 2; }
.r-2-3 { aspect-ratio: 2 / 3; }
.r-1-1 { aspect-ratio: 1 / 1; }
.r-3-4 { aspect-ratio: 3 / 4; }

.badge {
  position: absolute;
  background: var(--ink); color: var(--paper);
  padding: 12px 18px;
  font-family: var(--caps); font-size: 10px; letter-spacing: 0.30em;
  text-transform: uppercase;
}
.badge--hero { right: -24px; bottom: 32px; }
.badge--flag { left: -28px;  top: 40px; padding: 10px 16px; letter-spacing: 0.32em; }

/* ── Interior page masthead (About / Sustainability / Contact / Policies) ── */
.masthead { border-bottom: 1px solid var(--grey-line); }
.masthead__inner {
  padding-block: 64px 56px;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 80px; align-items: end;
}
.masthead h1 {
  font-family: var(--serif);
  font-size: clamp(64px, 9vw, 140px);
  line-height: 0.88; letter-spacing: -0.03em;
  margin-top: 28px;
}
.masthead h1 em { font-style: italic; font-weight: 300; color: var(--grey); }
.masthead__lede { color: var(--grey); font-size: 15px; line-height: 1.7; max-width: 420px; }

/* two-column body used by About + Sustainability */
.split {
  padding-block: 80px 120px;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 96px; align-items: start;
}
.split--tight { padding-bottom: 80px; }
.split h2 {
  font-family: var(--serif);
  font-size: clamp(32px, 4vw, 56px);
  line-height: 1; letter-spacing: -0.02em;
  margin-top: 24px;
}
.split h2 em { font-style: italic; font-weight: 300; color: var(--grey); }
.split__body { margin-top: 28px; display: grid; gap: 20px; }
.split__body p { font-size: 15px; line-height: 1.75; color: var(--grey); max-width: 480px; }

/* stacked key/value table with ink rules */
.facts-table {
  border: 1px solid #000;
  align-self: start;
  justify-self: start;
  width: 100%;
  max-width: 460px;
  margin-top: 60px;
}
.facts-table > div { padding: 20px 24px; }
.facts-table > div + div { border-top: 1px solid #000; }
.facts-table dt {
  font-family: var(--caps); font-size: 10px; letter-spacing: 0.26em;
  text-transform: uppercase; color: var(--grey); margin-bottom: 6px;
}
.facts-table dd { font-family: var(--serif); font-size: 26px; line-height: 1.2; margin: 0; }

/* ── Home: brand statement ───────────────────────────────────────────── */
.hero { padding-block: 56px 40px; }
.hero__grid { display: grid; grid-template-columns: 1.05fr 1fr; gap: 72px; align-items: end; }
.hero h1 {
  font-family: var(--serif);
  font-size: clamp(56px, 8vw, 128px);
  line-height: 0.9; letter-spacing: -0.03em;
  margin-top: 24px;
}
.hero h1 em { font-style: italic; font-weight: 300; color: var(--grey); }
.hero__cta { display: flex; gap: 12px; margin-top: 40px; flex-wrap: wrap; }

/* ── SITE SEARCH · two locations, one behaviour ──────────────────────────
   Added 15 Sep 2026 on Cazsper's instruction, replacing the hero box that
   shipped that morning.

     .hdr-find    in the header, left of Sign In, on EVERY page
     .tln-sugg    the suggestions dropdown

   The homepage band that sat under the header line was REMOVED on Cazsper's
   instruction, 15 Sep 2026, the same day it went in. The header box is the one
   search location now. Its markup is in git if it is ever wanted back.

   All of it lives in tln.css rather than shop.css because the header is on all
   275 pages and index.html loads tln.css ONLY. Putting any of it in shop.css
   would have looked right on the shop page and shipped an unstyled input to the
   homepage, about, contact and policies.

   16px on every input is the iOS Safari rule: anything smaller and Safari zooms
   the page on focus and never zooms back out. It is why the header field is
   sized with padding and width rather than with a smaller font. */

.hdr-find { position: relative; display: flex; }
.hdr-find__in {
  width: 210px; min-width: 0;
  font-family: var(--body); font-size: 16px; color: var(--ink);
  background: transparent;
  border: 1px solid var(--grey-line);
  padding: 7px 14px; min-height: 38px;
  transition: border-color 180ms ease;
}
/* WebKit reserves room inside a type="search" field for its own clear button,
   which is NOT in the box model. The placeholder measured as fitting with 12px
   to spare and still read as cramped, because that spare was underneath the
   clear affordance. Hiding it costs nothing · Escape still clears the field and
   the suggestions close with it. */
.hdr-find__in::-webkit-search-cancel-button,
.hdr-find__in::-webkit-search-decoration { -webkit-appearance: none; appearance: none; }
.hdr-find__in::placeholder { color: var(--grey); }
/* NO width change on focus. Growing the field reflowed the whole header row and
   nudged Sign In and Nest sideways under the cursor. The dropdown is already
   wider than the field, so the extra room is where it is actually needed. */
.hdr-find__in:focus { outline: none; border-color: var(--ink); }

/* ⚠ BOTH OF THESE ARE REGRESSION FIXES, measured at 1024px the first time the
   header search went in, and neither is cosmetic:

   1. The wordmark column is `auto` between two `1fr` columns, so when the two
      outer columns overflow it is the LOGO that absorbs it. Measured width went
      to EXACTLY 0px · the brand mark vanished from the header and nothing
      errored. `flex-shrink: 0` plus a min-width stops the grid taking it.
   2. "Sign In" wrapped to "SIGN / IN", making `.account` 54px tall against the
      Nest button's 44px and visibly misaligning the row. */
.header__inner > a[aria-label] { flex-shrink: 0; }
.wordmark { min-width: 104px; }
.account { white-space: nowrap; }
.hdr-find__in { flex-shrink: 0; }

/* ⚠ HIDDEN BELOW 980px, the same breakpoint that hides `.account`. Under that
   width the header collapses to menu / logo / actions and a fourth control does
   not fit on a 375px screen without a second row, which this layout has no
   place for. The consequence is real and deliberate: on a phone, search is the
   homepage band, the shop page's own filter box and each category page's filter
   box. Product, about, contact and policies pages have no search on mobile. */
/* ── Below 1100px: the search becomes its own full-width row ──────────────
   REPLACES an earlier `display: none`, which was the lazy answer and left every
   page below 1100px with no search at all except the shop and category filters.

   WHY 1140 AND NOT THE 980 USED FOR `.account`: measured, not guessed, twice.
   The overflow lands on the LOGO · its measured width went to exactly 0px the
   first time this was built, with no error anywhere.

   1100px was correct while the search field was 170px wide. The field was
   widened to 210px on 15 Sep 2026 because "Search products" rendered hard
   against the right edge, and a sweep from 1080 to 1240 in 10px steps then
   showed the single-row header overflowing at 1100 and 1120 and clean from
   1140. So this number is a FUNCTION OF THE FIELD WIDTH: change
   `.hdr-find__in` and re-run that sweep, do not assume this still holds.

   HOW: `.header__actions` becomes `display: contents`, which removes its box
   and promotes its children to grid items of `.header__inner`. The search can
   then be placed on row 2 spanning every column, while `.header__btns` stays in
   column 3 of row 1. No duplicated markup, no JavaScript, and therefore no
   second input to keep in step and no duplicate ids.

   `display: contents` is safe on this element specifically because it is a
   plain div carrying no role and no semantics worth preserving. Do not extend
   it to `<nav>`, `<header>` or anything with a landmark role.

   EVERY grid item is placed explicitly. Auto-placement with two rows and a
   promoted child put the wordmark on row 2 next to the search box the first
   time this was written. */
@media (max-width: 1139.98px) {
  .header__inner {
    grid-template-columns: auto 1fr auto;
    grid-template-rows: auto auto;
    column-gap: 24px;
    row-gap: 12px;
  }
  .nav-toggle { grid-column: 1; grid-row: 1; }
  .header__inner > nav.nav { grid-column: 1; grid-row: 1; }
  .header__inner > a[aria-label] { grid-column: 2; grid-row: 1; }

  .header__actions { display: contents; }
  .header__btns { grid-column: 3; grid-row: 1; justify-content: flex-end; }

  .hdr-find { grid-column: 1 / -1; grid-row: 2; display: flex; }
  .hdr-find__in { width: 100%; flex: 1 1 auto; }
  /* Full-bleed row, so the panel tracks the field rather than hugging the right
     edge the way it does beside Sign In on desktop. */
  .hdr-find .tln-sugg { left: 0; right: auto; min-width: 100%; max-width: 100%; }
}

/* ── Suggestions ───────────────────────────────────────────────────────────
   z-index 40 clears the sticky header's 30. Without that the dropdown opened
   BEHIND the header band on the homepage, where the two overlap by a few
   pixels, and the first suggestion was unclickable.

   Positioned against the FORM, so it lines up under the whole control rather
   than under the input alone · on the homepage the row also holds a Search
   button, and anchoring to the input made the panel sit visibly off-centre. */
.tln-sugg {
  position: absolute; z-index: 40;
  top: calc(100% + 6px); left: 0;
  min-width: 100%; max-width: 420px;
  margin: 0; padding: 6px 0; list-style: none;
  background: var(--paper);
  border: 1px solid var(--grey-line);
  box-shadow: 0 18px 40px rgba(28, 27, 23, 0.13);
  max-height: 60vh; overflow-y: auto;
}
/* 300 -> 340px on 15 Sep 2026, when the thumbnails went in. The tile plus its
   gap takes 56px out of the row, and at 300px that came off the NAME, which
   started wrapping to three lines on the longer Makers products. The panel is
   capped at 420px above, so this only widens it where there is room. */
.hdr-find .tln-sugg { left: auto; right: 0; min-width: 340px; }

.tln-sugg__row a, .tln-sugg__all a {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 10px 16px;
}
.tln-sugg__row a:hover, .tln-sugg__row.is-active a {
  background: var(--shiplap, rgba(28, 27, 23, 0.05));
}

/* ── Thumbnails in the suggestions, added 15 Sep 2026 on Cazsper's request ──
   Row reads photo · name · price.

   `align-items: center` OVERRIDES the `baseline` on the shared rule above, and
   only for `.tln-sugg__row`. Baseline is right for the two text spans and wrong
   the moment a 44px box joins them: the image would sit on the text baseline
   and hang below the row. `.tln-sugg__all` keeps baseline, which is why this is
   a separate rule rather than an edit to the shared one.

   ⚠ NOT `.ph`, DELIBERATELY, even though it is the same visual idea. `.ph` is
   `width: 100%` with a dashed inset border at 14px, which on a 44px tile is
   larger than the tile. It also carries the site-wide hover zoom added 11 Sep,
   which on a thumbnail this size reads as a wobble. A small dedicated class
   cannot disturb the shop grid; a shared one eventually would. The hatch is
   copied from `.ph` on purpose so the two read as the same empty state. */
.tln-sugg__row a { align-items: center; gap: 12px; }
.tln-sugg__ph {
  flex: 0 0 44px; width: 44px; height: 44px;
  position: relative; overflow: hidden;
  border: 1px solid var(--grey-line);
  background: repeating-linear-gradient(45deg, #f3f3f3 0 8px, #ececec 8px 16px);
}
.tln-sugg__ph--img { background: none; }
.tln-sugg__ph img { width: 100%; height: 100%; object-fit: cover; display: block; }

.tln-sugg__name {
  /* `min-width: 0` is load-bearing. A flex item defaults to min-width:auto and
     refuses to shrink below its longest word, so a long product name pushed the
     price out past the panel edge instead of wrapping. */
  flex: 1 1 auto; min-width: 0;
  font-family: var(--body); font-size: 14px; color: var(--ink);
  line-height: 1.35;
}
.tln-sugg__price {
  font-family: var(--body); font-size: 12px; color: var(--grey);
  white-space: nowrap;
}
.tln-sugg__none {
  padding: 12px 16px;
  font-family: var(--body); font-size: 13px; color: var(--grey);
}
.tln-sugg__all { border-top: 1px solid var(--grey-line); margin-top: 6px; padding-top: 2px; }
.tln-sugg__all a {
  font-family: var(--caps);
  font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ink);
}
.tln-sugg__all a:hover, .tln-sugg__all.is-active a {
  background: var(--shiplap, rgba(28, 27, 23, 0.05));
}

.hero__caption {
  font-family: var(--serif); font-style: italic;
  font-size: 18px; line-height: 1.5; color: var(--grey);
  max-width: 460px; margin-top: 20px;
}

.statement { padding-block: 80px 72px; }
.statement__grid { display: grid; grid-template-columns: 1fr 1.4fr; gap: 96px; align-items: start; }
.statement h2 {
  font-family: var(--serif);
  font-size: clamp(28px, 3vw, 44px);
  line-height: 1.1; letter-spacing: -0.01em;
}
.statement p { margin-top: 24px; color: var(--grey); max-width: 640px; line-height: 1.7; }

/* ── Marquee ─────────────────────────────────────────────────────────── */
.marquee {
  overflow: hidden;
  background: var(--ink); color: var(--paper);
  border-block: 1px solid rgba(255,255,255,0.15);
  padding-block: 18px;
}
.marquee__track {
  display: flex; width: max-content;
  font-family: var(--caps);
  font-size: 12px; letter-spacing: 0.32em; text-transform: uppercase;
  animation: marquee 28s linear infinite;
}
.marquee__track span { display: inline-flex; align-items: center; gap: 56px; padding-right: 56px; }
.marquee__track i { font-style: normal; opacity: 0.4; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .marquee__track { animation: none; } }

/* ── Triptych ────────────────────────────────────────────────────────── */
.triptych { padding-block: 80px; }
.triptych__head {
  display: flex; justify-content: space-between; align-items: end;
  gap: 32px; margin-bottom: 40px;
  /* WRAP, or this row is the one thing that overflows the page on a 320px
     screen. It holds the eyebrow and the "View All Products →" .ulink, and
     .ulink is `white-space: nowrap` (deliberately, the arrow must not orphan)
     so it cannot shrink below about 186px. Without wrapping, 320px gave
     scrollWidth 365 against clientWidth 320: 45px of horizontal scroll on the
     homepage, measured 17 Aug 2026. Every other width was already clean.
     Wrapping costs nothing above that: there is room for one line, so the row
     stays exactly as it was and space-between still holds the two ends apart. */
  flex-wrap: wrap;
  row-gap: 14px;
}
/* ⚠ THIS ONE LABEL IS CMS-EDITABLE, so its length is not this stylesheet's to
   assume. `home.triptych.viewall` is a `data-cms-link`, and `.ulink` is
   `white-space: nowrap`, which means a long label is a single unbreakable box.
   `flex-wrap` above cannot help with that: wrapping puts the item on its own
   line, and an item WIDER THAN THE LINE still overflows. Published
   "View Absolutely All Of Our Products Right Now" through the real CMS and the
   homepage scrolled sideways at every width below 480px, 465px of content in a
   320px viewport, with the fix for the short label already in place.
   Letting it wrap costs a possible orphaned arrow on a long label. Sideways
   scroll on every phone costs more. The built-in "View All Products →" is
   186px and still never wraps, so nothing changes for the site as shipped. */
.triptych__head .ulink { white-space: normal; max-width: 100%; }
.triptych h3 {
  font-family: var(--serif);
  font-size: clamp(36px, 4.4vw, 72px);
  line-height: 0.98; letter-spacing: -0.02em;
}
.triptych h3 em { font-style: italic; font-weight: 300; color: var(--grey); }
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; margin-top: 56px; }
.card__meta {
  padding-top: 24px;
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  font-family: var(--caps); font-size: 10px; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--grey);
}
.card h4 {
  font-family: var(--serif);
  font-size: 44px; line-height: 1; letter-spacing: -0.01em;
  margin: 12px 0 14px;
}
.card p { color: var(--grey); max-width: 360px; }
.card .ulink { display: inline-block; margin-top: 18px; letter-spacing: 0.24em; }
.card:hover h4 { font-style: italic; }

/* ── Featured product ────────────────────────────────────────────────── */
.featured {
  background: var(--paper);
  border-block: 1px solid var(--grey-line);
  padding-block: 88px;
}
.featured__grid { display: grid; grid-template-columns: 1.1fr 1fr; gap: 80px; align-items: center; }
.featured__media { position: relative; }
.featured h3 {
  font-family: var(--serif);
  font-size: clamp(36px, 4.4vw, 72px);
  line-height: 0.98; letter-spacing: -0.02em;
  margin-top: 20px;
}
.featured h3 em { font-style: italic; font-weight: 300; color: var(--grey); }
.featured p { margin-top: 24px; font-size: 15px; line-height: 1.65; max-width: 460px; }

.specs { margin-top: 32px; max-width: 560px; display: grid; grid-template-columns: 1fr 1fr; border: 1px solid #000; }
.spec { padding: 20px 22px; }
.spec:nth-child(2n) { border-left: 1px solid #000; }
.spec:nth-child(n+3) { border-top: 1px solid #000; }
.spec dt {
  font-family: var(--caps); font-size: 10px; letter-spacing: 0.26em;
  text-transform: uppercase; color: var(--grey);
}
.spec dd { font-family: var(--serif); font-size: 22px; line-height: 1.25; margin: 6px 0 0; }
.featured__cta { margin-top: 28px; display: flex; gap: 12px; flex-wrap: wrap; }

/* ── Ink anchor panel ────────────────────────────────────────────────── */
.anchor { background: var(--ink); color: var(--paper); padding-block: 100px; }
.anchor__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 80px; align-items: center; }
.anchor h3 {
  font-family: var(--serif);
  font-size: clamp(44px, 5.4vw, 88px);
  line-height: 0.94; letter-spacing: -0.02em;
  margin-top: 20px;
}
.anchor h3 em { font-style: italic; font-weight: 300; }
.anchor p { font-size: 15px; line-height: 1.7; color: rgba(255,255,255,0.85); max-width: 520px; }
.anchor__cta { margin-top: 36px; }

/* Steph, 19 Sep 2026: "on the left-hand side the line of the box has
   disappeared ... The details need to be centred inside the box, or in from the
   left-hand side margin, the same as on the About page."

   She is describing a real difference, not a rendering fault. This box used to
   be drawn OPEN on the left: a border-top on the grid, a border-bottom and
   border-right on every cell, and `padding-left: 0` so the figures sat flush
   against the edge that was not there.

   It is now drawn the same way as `.specs` twelve rules above it (the box in
   The Feature, on this same page) and `.facts-table` on About and
   Sustainability: ONE border round the whole box, symmetric padding, and the
   internal rules carried by nth-child. Same idiom, three places, so a future
   edit to one is obvious in the others. Only the rule COLOUR differs, because
   this box sits on the ink panel and those sit on paper. */
.facts {
  display: grid; grid-template-columns: 1fr 1fr; margin-top: 40px;
  border: 1px solid rgba(255,255,255,0.2);
}
.fact { padding: 32px 24px; }
.fact:nth-child(2n) { border-left: 1px solid rgba(255,255,255,0.2); }
.fact:nth-child(n+3) { border-top: 1px solid rgba(255,255,255,0.2); }
.fact dt { font-family: var(--serif); font-size: 56px; line-height: 1; }
.fact dd {
  font-family: var(--caps); font-size: 10px; letter-spacing: 0.28em;
  text-transform: uppercase; color: rgba(255,255,255,0.6);
  margin: 10px 0 0;
}

/* ── Testimonials ────────────────────────────────────────────────────── */
.words { padding-block: 96px 72px; }
.words h3 {
  font-family: var(--serif);
  font-size: clamp(28px, 3.2vw, 48px);
  line-height: 1.1; letter-spacing: -0.01em;
  margin: 20px 0 48px; max-width: 900px;
}
.quotes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 48px; }
.quote { margin: 0; }
.quote__mark { font-family: var(--serif); font-size: 44px; line-height: 0.6; margin-bottom: 8px; }
.quote blockquote { margin: 0; font-family: var(--serif); font-style: italic; font-size: 17px; line-height: 1.5; }
.quote figcaption {
  margin-top: 28px; padding-top: 18px;
  border-top: 1px solid #000;
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
}
.quote figcaption b {
  font-family: var(--caps); font-weight: 400;
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
}
.quote figcaption span { color: var(--grey); font-size: 12px; }

/* ── Image strip + closer ────────────────────────────────────────────── */
.strip { padding-bottom: 96px; }
.strip__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }

.closer { border-top: 1px solid var(--grey-line); padding-block: 72px; }
.closer__inner { display: flex; justify-content: space-between; align-items: end; gap: 56px; }
.closer h3 {
  font-family: var(--serif);
  font-size: clamp(28px, 3.4vw, 52px);
  line-height: 1.02; letter-spacing: -0.02em;
  max-width: 800px;
}

/* ── Contact ─────────────────────────────────────────────────────────── */
.contact { padding-block: 80px 120px; display: grid; grid-template-columns: 1fr 1.2fr; gap: 96px; align-items: start; }
.details { margin-top: 40px; display: grid; gap: 40px; }
.details dt {
  font-family: var(--caps); font-size: 10px; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--grey); margin-bottom: 12px;
}
.details dd { margin: 0; font-family: var(--serif); font-size: 20px; line-height: 1.4; }
.details dd.is-link { font-size: 24px; }
.details dd a { border-bottom: 1px solid #000; padding-bottom: 2px; }
.details dd em { font-style: italic; font-weight: 300; color: var(--grey); }
.details dd.is-muted { color: var(--grey); }

/* Capped · full-column-width single-line inputs are hard to scan. */
.form { margin-top: 40px; display: grid; gap: 20px; max-width: 560px; }
.field { display: block; }
.field > span {
  display: block;
  font-family: var(--caps); font-size: 9px; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--grey); margin-bottom: 8px;
}
.field input, .field textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--grey-soft); border-radius: 0;
  font-family: var(--body); font-size: 14px; line-height: 1.6;
  background: var(--paper); color: var(--ink);
}
.field textarea { resize: vertical; min-height: 118px; }
.field input:focus, .field textarea:focus { border-color: var(--ink); }
.form__note { margin-top: 20px; font-size: 12px; color: var(--grey); line-height: 1.6; }
.form__submit { margin-top: 28px; }

/* ── Policies ────────────────────────────────────────────────────────── */
.policies { padding-block: 80px 120px; }
.policies__inner { max-width: 860px; display: grid; gap: 80px; }
.policy h2 {
  font-family: var(--serif);
  font-size: clamp(36px, 4vw, 60px);
  line-height: 0.98; letter-spacing: -0.02em;
  margin: 20px 0 32px;
}
.policy__body { display: grid; gap: 14px; }
.policy__body p { font-size: 15px; line-height: 1.75; color: var(--grey); max-width: 720px; }
.policy__body strong { color: var(--ink); font-weight: 500; }
.rule { height: 1px; background: var(--grey-line); }

.freight { display: grid; grid-template-columns: repeat(4, 1fr); border: 1px solid #000; margin: 28px 0; }
.freight > div { padding: 18px 20px; }
.freight > div + div { border-left: 1px solid #000; }
.freight dt {
  font-family: var(--caps); font-size: 10px; letter-spacing: 0.26em;
  text-transform: uppercase; color: var(--grey); margin-bottom: 8px;
}
.freight dd { font-family: var(--serif); font-size: 28px; line-height: 1; margin: 0; }

/* ── Footer ──────────────────────────────────────────────────────────── */
.footer { background: var(--cream); border-top: 1px solid var(--grey-line); padding-block: 80px 36px; }
.footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 48px; }
.footer__blurb { margin-top: 28px; color: var(--grey); max-width: 320px; font-size: 13px; }
.footer h2 {
  font-family: var(--caps); font-weight: 400;
  font-size: 11px; letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--grey); margin-bottom: 22px;
}
.footer li + li { margin-top: 12px; }
.footer li a { border-bottom: 1px solid transparent; }
.footer li a:hover { border-bottom-color: var(--ink); }
.footer__email { font-family: var(--serif); font-size: 18px; line-height: 1.4; }
.footer__meta { margin-top: 6px; color: var(--grey); }
.footer__hours { margin-top: 16px; color: var(--grey); font-size: 12px; }
.footer__rule { height: 1px; background: var(--grey-line); margin: 56px 0 24px; }
.footer__base {
  display: flex; justify-content: space-between; align-items: center; gap: 24px;
  font-family: var(--caps); font-size: 10px; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--grey);
}

/* ══ Responsive ═══════════════════════════════════════════════════════ */
@media (max-width: 1080px) {
  .hero__grid, .statement__grid, .featured__grid, .anchor__grid,
  .split, .contact, .masthead__inner, .trade__inner { gap: 48px; }
  .cards, .quotes { gap: 28px; }
}

@media (max-width: 980px) {
  :root { --pad: 32px; }
  .header__inner { grid-template-columns: auto 1fr auto; }
  .nav {
    display: none;
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: flex-start; gap: 0;
    background: var(--shiplap);
    border-bottom: 1px solid var(--grey-line);
    padding: 8px var(--pad) 24px;
  }
  .nav[data-open="true"] { display: flex; }
  .nav a { padding-block: 14px; }
  .nav-toggle {
    display: inline-flex; align-items: center;
    font-family: var(--caps); font-size: 11px; letter-spacing: 0.22em;
    text-transform: uppercase;
    background: transparent; border: 1px solid var(--grey-line);
    color: var(--ink); padding: 8px 14px; cursor: pointer;
  }
  .account { display: none; }

  .hero__grid, .statement__grid, .featured__grid, .anchor__grid,
  .split, .contact, .masthead__inner, .trade__inner { grid-template-columns: 1fr; }
  .hero__grid { gap: 40px; }
  /* Badges clear the placeholder caption, which sits bottom-left. */
  .badge--hero { right: 0; bottom: auto; top: 24px; }
  .badge--flag { left: 0; }
  .facts-table { margin-top: 0; }
  .cards, .quotes { grid-template-columns: 1fr; gap: 56px; }
  .strip__grid { grid-template-columns: 1fr 1fr; }
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 40px; }
  .closer__inner { flex-direction: column; align-items: flex-start; gap: 32px; }
  .freight { grid-template-columns: 1fr 1fr; }
  .freight > div:nth-child(3) { border-left: 0; }
  .freight > div:nth-child(n+3) { border-top: 1px solid #000; }
}

@media (max-width: 720px) {
  :root { --pad: 24px; }
  /* Keep the header wordmark on one line; the strapline returns in the footer. */
  .header__inner { gap: 12px; }
  .header .wordmark-text b { font-size: 12px; letter-spacing: 0.18em; }
  .header .wordmark-text i { display: none; }
  /* The header is a three-column grid on a 375px screen. At 44px the lockup is
     136px wide and squeezes the nav toggle and the cart button. */
  .wordmark { height: 30px; }
  .wordmark--foot { height: 62px; }
  .cart { padding: 10px 14px; }

  .statement, .triptych { padding-block: 56px; }
  .featured, .anchor, .trade { padding-block: 56px; }
  .announce p { font-size: 9px; letter-spacing: 0.18em; }
  .words { padding-block: 64px 48px; }
  .split, .contact, .policies { padding-block: 56px 80px; }
  .policies__inner { gap: 56px; }

  .specs, .facts { grid-template-columns: 1fr; }
  .spec:nth-child(2n) { border-left: 0; }
  .spec + .spec { border-top: 1px solid #000; }
  /* One column, so the vertical divider goes and EVERY cell after the first
     takes the horizontal one. Mirrors the two .spec rules above it. */
  .fact:nth-child(2n) { border-left: 0; }
  .fact + .fact { border-top: 1px solid rgba(255,255,255,0.2); }

  .freight { grid-template-columns: 1fr; }
  .freight > div + div { border-left: 0; border-top: 1px solid #000; }

  .footer__grid { grid-template-columns: 1fr; }
  .footer__base { flex-direction: column; align-items: flex-start; gap: 10px; }
  .btn { padding: 16px 26px; font-size: 11px; }
}

/* --- embedded Zoho enquiry form ---------------------------------------------
   Added 6 Aug 2026. The form itself is Zoho's, in an iframe, because a
   cross-origin POST to Zoho Forms is rejected silently and a lost enquiry is
   worse than mismatched typography. These rules stop it reading as a bolted-on
   widget: full column width, no chrome, and a min-height so the box is the
   right size before Zoho's resize message arrives · and if it never does. */
.form-embed {
  margin-top: 40px;
  max-width: 560px;
  background: var(--paper);
  border: 1px solid var(--grey-line);
}
.form-embed iframe {
  display: block;
  width: 100%;
  min-height: 620px;
  border: 0;
}

/* 320px reflow, added 23 Sep 2026. Between 320 and 328px the header row
   (search, Sign In, the Nest button) was 7px wider than the screen and the
   whole page scrolled sideways. Tightened only below 340px. */
@media (max-width: 340px) {
  .header__btns { gap: 8px; }
  .cart { padding: 8px 10px; }
}
