/* ==========================================================================
   DINKOMART — REFINE
   The enhancement layer. Loads LAST, after mobile.css.

   ---------------------------------------------------------------------------
   WHAT THIS FILE IS FOR

   The build underneath is not badly made — the token system, the fluid type
   ratios, the semantic light/dark split and the warm shadow scale are all
   better than average. What made it read as generic was never the colour:

     1. NO SCALE CONTRAST. Section headings computed to 34px while the hero
        computed to 51px, so nine sections all felt like the same size and
        the page had no hierarchy to travel down.
     2. NO RHYTHM VARIATION. Every section is eyebrow → h2 → lede → see-all →
        rule → grid. Nine times. Content changed; structure never did.
     3. CARDS THAT STOP AT COMPETENT. A hover lift and an image zoom, and
        nothing else — no reason to look at one card over another.
     4. MOTION WITH ONE NOTE. Everything arrives by fading up. Nothing is
        scroll-linked, nothing responds to the pointer, nothing rewards
        attention.

   So this file adds craft rather than replacing anything. It is additive on
   purpose: the eighty kilobytes of craft.css underneath keep working, and
   deleting one <link> puts the site back exactly as it was.

   ---------------------------------------------------------------------------
   RULES OBSERVED (all four have already caused a bug in this codebase)

   * Only SEMANTIC tokens are painted. Never --bone-*, --loam-* or --forest-*:
     raw tokens do not flip with the theme, so a tint authored in light mode
     paints that same colour across every dark page.
   * Nothing here hides content and waits for JS to bring it back. Every rule
     below is a visual refinement of something already visible.
   * This file must stay LAST in the <link> order. It is written to win on
     source order, not on specificity wars, so it contains almost no !important.
   * Load order of the existing links is untouched.
   ========================================================================== */

/* ==========================================================================
   1. SCALE — the single biggest lever.

   The type scale in tokens.css is well-built and barely used: --t-3xl and
   --t-4xl exist but section headings were set at --t-2xl. Raising section
   headings and lowering the mono labels widens the gap between the biggest
   and smallest thing on screen, which is what "designed" actually looks like.
   ========================================================================== */
.sec-head h2,
.section-title {
  font-size: clamp(2.1rem, 1.55rem + 2.5vw, 3.4rem);
  line-height: 1.02;
  letter-spacing: -0.032em;
}

/* the hero gets to be genuinely large */
.hero-title {
  letter-spacing: -0.042em;
  line-height: 0.92;
}

/* and the labels get genuinely small, so the gap is real at both ends */
.sec-num {
  font-size: 0.6875rem;
  letter-spacing: 0.2em;
}

/* The section marker measured 3.85:1 against the alternating --rhythm wash on
   farm-box, farmers and about — --fg-faint is documented as "4.7:1 on bone,
   the floor, not decoration", and the wash puts it under the floor. One step
   up clears it everywhere without changing the hierarchy. */
.sec-num { color: var(--fg-muted); }

/* THE BAND OVERRIDE HAS TO BE RESTATED HERE.

   craft.css:83 already has `.on-band .sec-num { color: var(--band-fg-faint) }`.
   Both that and the `.sec-head .sec-num` rule further down this file are
   specificity (0,2,0) — so the one that wins is whichever comes LAST, and
   refine.css loads last by design. The first pass therefore painted the
   light theme's --fg-muted onto three dark bands and took the marker from
   3.85:1 to 2.43:1, which is worse than the problem it was fixing.

   Restating it after our own rules puts the band back in charge. Anything
   else added to .sec-head below needs the same treatment. */
.on-band .sec-num,
.band .sec-num { color: var(--band-fg-muted); }

/* the lede stops competing with the heading */
.sec-head p,
.sec-head-copy > p {
  max-width: 52ch;
  font-size: var(--t-md);
  line-height: 1.55;
  color: var(--fg-subtle);
}

/* ==========================================================================
   2. RHYTHM — break the nine-identical-sections pattern.

   The section marker moves out of the flow and into the left margin as a
   numbered index entry with its own rule. On wide screens the heading block
   sits beside it rather than under it, so a section reads as an indexed
   chapter rather than another stacked card. Below 1100px it folds back to
   the original arrangement, so nothing is lost on a phone.
   ========================================================================== */
@media (min-width: 1100px) {
  .sec-head {
    /* the marker is placed against this, see below */
    position: relative;
    display: grid;
    grid-template-columns: 148px minmax(0, 1fr) auto;
    align-items: start;
    column-gap: var(--s-8);
  }
  .sec-head .sec-head-copy { grid-column: 2; }
  .sec-head > .see-all,
  .sec-head > .cluster { grid-column: 3; align-self: end; }

  /* THE MARKER IS NOT A GRID ITEM, AND THAT IS WHY THIS BLOCK USED TO BREAK.

     Every one of the nineteen section heads authors the marker *inside*
     .sec-head-copy — `<div class="sec-head-copy"><span class="sec-num">…`.
     So `grid-column: 1` had nothing to place: the marker stayed in the copy
     column, and `display: block` stretched it the full 62ch of it. The 2px
     brand rule ran 567px across the heading instead of 148px, and the
     numeral below inherited the chip geometry from craft.css — height 20px,
     rounded, backgrounded — which as a block box became a full-width bar
     with 24px digits spilling out of it. micro.css:162 then filled that bar
     solid --accent on arrival. That was the orange smear.

     Placing it against .sec-head puts it in the gutter the grid already
     reserves, without editing nineteen blocks of markup. Out of flow is the
     right answer twice over: the heading then starts at the top of the row
     rather than under the marker's old margin, which is the alignment the
     indexed-chapter reading wants. */
  .sec-head .sec-num {
    position: absolute;
    left: 0;
    top: 0;
    width: 148px;
    display: block;
    margin-bottom: 0;
    padding-top: 0.55em;
    border-top: 2px solid var(--brand);
    line-height: 1.45;
    /* --fg-faint measured 3.85:1 here — it is documented as the 4.7:1 floor
       on bone, and the alternating --rhythm wash pushes it under. This
       selector is more specific than the .sec-num rule above, so it has to
       carry the corrected value itself. */
    color: var(--fg-muted);
  }
  .on-band .sec-head .sec-num,
  .band .sec-head .sec-num { color: var(--band-fg-muted); border-top-color: var(--band-accent); }

  /* [data-n] IS LOAD-BEARING, NOT DECORATION.

     craft.css:69 draws this as a small filled chip and micro.css:162 fills it
     solid on `.sec-head.is-in`. Both have to lose here, and micro's selector
     is (0,3,1) — a plain `.sec-head .sec-num::before` at (0,2,1) does not
     out-rank it, whichever file loads last. The attribute takes this rule to
     (0,3,1) too, and refine.css loads after micro.css, so the tie goes here.
     The marker is a numeral in the margin now, not a chip; the chip geometry
     and the arrival fill both have to be undone explicitly. */
  .sec-head .sec-num[data-n]::before {
    content: attr(data-n);
    display: block;
    min-width: 0;
    height: auto;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    font-size: 1.75rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    color: var(--brand);
    line-height: 1;
    margin-bottom: 0.45rem;
  }
  /* micro.css:164 fills the chip a second time for bands, at (0,4,1) — one
     step above the rule directly above, so that one clears the light fill and
     leaves the band fill behind. Orange numeral on an orange block reads as a
     blank swatch. Same tie-break, one selector wider. */
  .on-band .sec-head .sec-num[data-n]::before,
  .band .sec-head .sec-num[data-n]::before { background: none; color: var(--band-accent); }
}

/* Alternating sections get a different ground, so the page has strata
   instead of one continuous wash. --rhythm is semantic and flips correctly;
   the raw-token version of this is what put a grey smear down every dark
   page in an earlier build.

   ONE RULE, NOT TWO. This shipped twice. atmosphere.css §5 had it as a
   feathered gradient excluding `.mach-band`; this file had it flat, excluding
   `.contour-bg`. Both are (0,4,1) and refine loads last, so wherever the two
   selectors overlapped the FLAT one won — the softer version never shipped at
   all, and `.mach-band` lost the half-step surface that atmosphere.css:55
   goes out of its way to protect. Consolidated here with both exclusions and
   the feathered edges. The dead copy in atmosphere.css is gone. */
.section:nth-of-type(even):not(.band):not(.mach-band):not(.contour-bg) {
  background: linear-gradient(180deg, transparent, var(--rhythm) 16%, var(--rhythm) 84%, transparent);
}

/* ==========================================================================
   3. CARDS — from competent to worth looking at.
   ========================================================================== */

/* --- the lift. Slightly further, and the border becomes the brand ------ */
.pcard {
  transition:
    transform var(--dur-2) var(--ease-out),
    border-color var(--dur-2) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out);
}
.pcard:hover {
  transform: translateY(-4px);
  border-color: var(--brand);
  box-shadow: var(--shadow-lg);
}

/* --- (WAS: a hairline that drew along the top edge on hover.) -------------
   REMOVED 2026-09-06, reported as "the top border is cut off".

   It was a 2px brand-coloured bar at `inset: 0 0 auto 0`, and four lines above
   this the same hover ALSO turns the card's own border brand-coloured. So the
   top edge of a hovered card carried TWO green lines at the same place: a
   0.8px one that follows the 18px corner radius all the way round, and a 2px
   one that does not.

   `.pcard` is `overflow: hidden`, so the bar was clipped by that radius to a
   chord — it stopped well short of both corners and ended bluntly against a
   border two and a half times thinner than itself. Nothing about that reads
   as a drawn hairline; it reads as a border with its corners missing.

   The border is the one that survives, because it goes all the way round.
   If a draw-on-hover is ever wanted back, it cannot live inside a clipped
   radius — it has to BE the border (an animated `inset` box-shadow), or sit
   between the corners (`inset: 0 var(--r-card) auto var(--r-card)`) so it
   never meets the curve and reads as a deliberate short rule. */

/* --- the price. Tabular, larger, and the MRP recedes ------------------- */
.pcard-foot b,
.pcard-foot .price,
.spec-card-foot b {
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.pcard-foot s { opacity: .62; font-variant-numeric: tabular-nums; }

/* --- the proof line earns its place ----------------------------------- */
.pcard-proof {
  color: var(--fg-subtle);
  line-height: 1.45;
}
.pcard-proof .ico { color: var(--brand); }

/* --- media: a slower, softer zoom, and a wash that lifts on hover ------ */
.pcard-media img { transition: transform 900ms var(--ease-soil), filter 400ms var(--ease-out); }
.pcard:hover .pcard-media img { transform: scale(1.055); }

/* --- the save control stays reachable on touch ------------------------- */
@media (hover: none) {
  .pcard-save { opacity: 1; transform: none; }
}

/* --- category cards: a stronger scrim so the label always reads -------- */
.cat-card { transition: transform var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out); }
.cat-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }

/* --- specimen cards: the figures get emphasis, being the reason to buy - */
.spec-card { transition: transform var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out); }
.spec-card:hover { transform: translateY(-4px); border-color: var(--accent); box-shadow: var(--shadow-lg); }

/* ==========================================================================
   4. BUTTONS — press, focus and a single moving highlight.
   ========================================================================== */
.btn {
  position: relative;
  overflow: hidden;
  transition:
    background-color var(--dur-1) var(--ease-out),
    color var(--dur-1) var(--ease-out),
    border-color var(--dur-1) var(--ease-out),
    transform var(--dur-1) var(--ease-out),
    box-shadow var(--dur-2) var(--ease-out);
}
.btn:active { transform: translateY(1px) scale(.994); }

/* a highlight that sweeps once on hover. Uses currentColor so it works on
   every variant and in both themes without a second rule. */
.btn-brand::after,
.btn-accent::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.22) 50%, transparent 62%);
  transform: translateX(-120%);
  transition: transform 620ms var(--ease-out);
  pointer-events: none;
}
.btn-brand:hover::after,
.btn-accent:hover::after { transform: translateX(120%); }
@media (prefers-reduced-motion: reduce) {
  .btn-brand::after, .btn-accent::after { display: none; }
}

.btn-brand:hover  { box-shadow: var(--glow-brand); }
.btn-accent:hover { box-shadow: var(--glow-accent); }

/* one focus treatment for every interactive thing on the site */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--border-focus);
  outline-offset: 3px;
  border-radius: var(--r-chip);
}

/* ==========================================================================
   5. DETAIL — the small things that add up.
   ========================================================================== */

/* every price on the site aligns in a column */
.price, .pcard-foot b, .cart-row b, [data-cart-total], [data-cart-subtotal],
[data-cart-delivery], .hero-stat dd {
  font-variant-numeric: tabular-nums;
}

/* selection matches the brand rather than the browser default */
::selection { background: var(--brand); color: var(--brand-fg); }

/* a link in running copy: an underline that thickens rather than a colour flip */
.prose a:not(.btn):not(.see-all),
.copy a:not(.btn):not(.see-all),
.lede a:not(.btn) {
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition: text-decoration-thickness var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.prose a:not(.btn):hover,
.copy a:not(.btn):hover { text-decoration-thickness: 3px; color: var(--brand-ink); }

/* THE MISSING BAND OVERRIDE.

   `.step p` is set to --fg-muted in components.css:576 and has no .on-band
   counterpart, so the three step descriptions in the "Sell into the line"
   section render #46574A on the band's #06150D ground. Measured at 2.43:1 —
   dark grey text on a near-black band, effectively unreadable.

   The build already has .on-band overrides for .sec-head p, .badge, .fact,
   .seal, .see-all and .rail-btn. This one was simply missed, and it is the
   only remaining contrast failure on the home page in either theme. */
.on-band .step p,
.on-band .crate-list li,
.on-band .lineage-text { color: var(--band-fg-muted); }
.on-band .step h3 { color: var(--band-fg); }

/* THE STEP'S PSEUDO-ELEMENTS WERE MISSED BY THE SAME PASS.

   `.step p` and `.step h3` above were corrected for the band; the node and the
   rail were not, and both were wrong in opposite directions in opposite
   themes. Measured on the #farmers band:

     node  --accent-ink  light 2.77:1  (dark amber on near-black, unreadable)
                          dark 8.86:1  (fine, by luck — the token flips)
     rail  --border      light 15.15:1 (a bright grey line screaming on black)
                          dark  1.59:1 (invisible)

   Both now read against the band's own palette, which is dark in either
   theme, so one value serves both. */
.on-band .steps { border-top-color: var(--band-hairline); }
.on-band .step { border-bottom-color: var(--band-hairline); }
.on-band .step::before {
  background: rgba(255, 255, 255, .05);
  border-color: var(--band-border);
  color: var(--band-accent);
}
.on-band .step:hover::before {
  background: var(--band-accent);
  border-color: var(--band-accent);
  color: #1A0D02;                     /* the band chip ink, as in micro.css */
}
.on-band .step::after { background: var(--band-accent); }

/* The result count inside a filter option.

   Measured at 4.47:1 — --fg-subtle (#5F6E63) sitting on the selected
   option's --brand-soft ground (#DDEEE3), which is a hair under the 4.5
   needed at 11px. It passes comfortably on the page background and only
   fails on the SELECTED state, which is exactly the kind of thing an
   eyeball check misses. --fg-muted clears it in both themes. */
.filter-opt .n,
.rail-opt .n,
.mega-link .n { color: var(--fg-muted); }

/* the see-all arrow travels */
.see-all .ico { transition: transform var(--dur-2) var(--ease-out); }
.see-all:hover .ico { transform: translateX(4px); }

/* section rules draw rather than appear */
.sec-rule {
  transform-origin: 0 50%;
  transition: transform var(--dur-4) var(--ease-out);
}
.m-ready .sec-rule:not(.is-in) { transform: scaleX(0); }
.sec-rule.is-in { transform: scaleX(1); }

/* THE CLIPPED TOUCH TARGET.

   craft.css and hero.css both carry a considered fix for the hero carousel
   dots: the bar stays 3px and an invisible `::before { inset: -20px -4px }`
   carries a 44px hit area, under @media (pointer: coarse). The comment above
   it in craft.css even explains the reasoning.

   `.hero-dot` also has `overflow: hidden`, which clips that ::before back to
   the 3px box — so on a real touch device the fix silently does nothing and
   the target is 3px tall again.

   The overflow was there to contain the progress fill, but the fill is
   `::after { inset: 0; border-radius: inherit }` scaled on X from a left
   origin, so it can never leave the dot's box. Nothing needs clipping, and
   removing it lets the intended hit area work.

   Note: do NOT give .hero-dot an ::after here. That pseudo-element IS the
   progress fill — overwriting it stops the carousel showing its position. */
.hero-dot { overflow: visible; }

/* the scroll progress rule, painted by refine.js */
.read-bar {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2px;
  z-index: calc(var(--z-nav) + 1);
  background: var(--accent);
  transform: scaleX(var(--read, 0));
  transform-origin: 0 50%;
  pointer-events: none;
}

/* the header earns its separation only once you have scrolled */
.site-nav {
  transition: box-shadow var(--dur-2) var(--ease-out),
              background-color var(--dur-2) var(--ease-out),
              border-color var(--dur-2) var(--ease-out);
}
.site-nav.is-stuck { box-shadow: var(--shadow-md); }

/* hero stats: bigger figures, quieter labels — more contrast, same layout */
.hero-stat dd {
  font-size: clamp(1.7rem, 1.2rem + 2.2vw, 2.6rem);
  letter-spacing: -0.03em;
  line-height: 1;
}
.hero-stat dt {
  font-size: var(--t-2xs);
  letter-spacing: 0.18em;
}

/* ==========================================================================
   6. MOTION — a second and third note.

   The build had one: fade-and-rise on scroll. These add a pointer-reactive
   tilt on media and a scroll-linked drift, both of which self-disable on
   coarse pointers and under reduced motion.
   ========================================================================== */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  [data-tilt] {
    transform: perspective(1000px)
               rotateX(calc(var(--ty, 0) * -3.2deg))
               rotateY(calc(var(--tx, 0) * 3.2deg));
    transition: transform var(--dur-2) var(--ease-out);
    transform-style: preserve-3d;
  }
}

/* a plate that lifts its caption on hover */
.split-media, .hero-frame { transition: box-shadow var(--dur-3) var(--ease-out); }
.split-media:hover, .hero-frame:hover { box-shadow: var(--shadow-xl); }

/* ==========================================================================
   7. RESPONSIVE — the "fully responsive" part of the brief.

   The build was already free of horizontal overflow at 390px, which is more
   than most sites manage. What it was missing was mobile TYPOGRAPHY and tap
   targets: the desktop rhythm simply scaled down, so headings ran long and
   controls landed under the 44px minimum.
   ========================================================================== */
@media (max-width: 720px) {
  /* headings stop wrapping to four words a line */
  .sec-head h2, .section-title { font-size: clamp(1.75rem, 1.3rem + 3.4vw, 2.2rem); letter-spacing: -0.026em; }
  .hero-title { font-size: clamp(2.2rem, 1.2rem + 8vw, 3.2rem); }

  /* the section marker returns above the heading, with its rule intact */
  .sec-head .sec-num { border-top: 2px solid var(--brand); padding-top: .5em; display: inline-block; }

  /* every control clears the 44px minimum */
  .btn { min-height: 46px; }
  .btn-sm { min-height: 40px; }
  .icon-btn { min-width: 44px; min-height: 44px; }
  .pcard-save { width: 40px; height: 40px; }

  /* cards get more room to breathe than the desktop grid gives them */
  .pcard-body { padding: 14px 14px 0; }
  .pcard-foot { padding: 12px 14px 14px; }

  /* stats become two columns rather than four squeezed ones */
  .hero-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* the section rhythm tightens so a phone is not all whitespace */
  .section { padding-block: var(--sec-y-sm); }
}

@media (max-width: 420px) {
  /* below this the two-up product grid stops being readable */
  .cat-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Wide screens: the container was capped at 1320px, which leaves a lot of
   desk empty on a 1600px display without ever using it. */
@media (min-width: 1600px) {
  .wrap { max-width: var(--container-wide); }
}

/* ==========================================================================
   8. PRINT — an order confirmation is the one thing people print.
   ========================================================================== */
@media print {
  .site-nav, .ticker, .site-footer, .cart-drawer, .nav-drawer,
  .toast-zone, .read-bar, [data-wa-fab], .scrim { display: none !important; }
  body { background: #fff; color: #000; }
  .section { padding-block: 12px; }
  a[href^="http"]::after { content: ' (' attr(href) ')'; font-size: var(--t-2xs); }
}

/* ==========================================================================
   9. THE VERIFICATION HATCH

   Preview renderers in this environment do not advance animations, so a
   contrast or layout check reads phantom values off components caught
   mid-transition — several "failures" during this build were measurement
   artefacts before this existed.

       document.documentElement.dataset.flat = '1'

   kills every transition and animation AND resolves every reveal to its end
   state. Set it BEFORE flipping data-theme, never after, or the numbers come
   off components still mid-flip.
   ========================================================================== */
[data-flat] *,
[data-flat] *::before,
[data-flat] *::after {
  transition: none !important;
  animation: none !important;
}
[data-flat] [data-rise],
[data-flat] [data-stagger] > *,
[data-flat] [data-words],
[data-flat] .reveal {
  opacity: 1 !important;
  transform: none !important;
}
[data-flat] .sec-rule { transform: scaleX(1) !important; }

/* ==========================================================================
   10. THE HEADER FITS AT EVERY WIDTH

   Found by the 2026-09-02 responsive sweep, and it was on all ten pages at
   once because the header is shell.

   THE BRAND WAS PAYING FOR EVERY OTHER ITEM IN THE BAR.

   `.nav-in` is a nowrap flex row of brand · links · search · tools. Three of
   those four carry the default `min-width: auto`, which refuses to shrink
   below their content. `.brand` is the only one with `min-width: 0` — put
   there on purpose so the wordmark can truncate — and `.brand-text` has
   `overflow: hidden` behind it. So the WHOLE of any deficit, however it
   arose, came out of the company's own name.

   Measured at 1280 before the fix: the bar needed 1386px of content in a
   1208px content box, and `.brand-text` resolved to 57px against a
   `.brand-name` that needs 127. The header read "DINKO". At 390 it resolved
   to SIX pixels — a sliver of the D — against 252px of icon buttons.

   Neither was an overflow bug: `scrollWidth` equalled the viewport on both,
   because the truncation was busy hiding the evidence. That is why it had
   survived — nothing that looks for horizontal scroll can see it.

   The fix is a ladder rather than one breakpoint, because what has to give
   is different at each size. The rule throughout: SHOW THE WORDMARK WHOLE OR
   NOT AT ALL. Half a word looks broken; the mark alone is a logo.
   ========================================================================== */

/* --- desktop: the six links, the search field and four tool buttons ----- */

/* THE ORDER OF SACRIFICE IS THE WHOLE FIX.

   Tightening alone was measured and is not enough — it moved 1280 from
   `.brand-text` 57px to 100px against a name needing 127, which is still a
   cut word. The deficit has to stop landing on the brand at all.

   So the brand leaves the shrink pool, and the SEARCH FIELD becomes the
   thing that gives, with a floor under it so it stays a usable input rather
   than the 60px stub it collapses to when it absorbs the squeeze unbounded.
   A search box that is narrower than it might be costs a visitor nothing; a
   masthead reading "DINKO" costs the brand. */
@media (min-width: 1080px) {
  .brand { flex: 0 0 auto; }
  .nav-search { min-width: 150px; }
}

/* From 1080 up to 1440 the six links, the field and four tool buttons still
   crowd a 267px brand, so the bar tightens in two steps.

   The band ends at 1439 and not at 1359, which was measured: at exactly 1360
   craft.css's `.nav-search { margin-inline: var(--s-5) }` came back at the
   same moment the tagline did, adding 56px of margin plus 40px of brand, and
   `.nav-tools` ran to 1364 in a 1360px window. 1440 is the first width where
   the loose bar demonstrably fits. */
@media (min-width: 1080px) and (max-width: 1439px) {
  .nav-in { gap: var(--s-3); }
  .nav-search { margin-inline: var(--s-3); }
  .brand-tag { display: none; }
}

/* Step one, the tightest: laptops between the breakpoint and 1280. */
@media (min-width: 1080px) and (max-width: 1279px) {
  .nav-links { gap: 0; }
  .nav-link { padding-inline: var(--s-2); }
}

/* Step two: room to give the links their spacing back, not yet enough for
   the tagline. */
@media (min-width: 1280px) and (max-width: 1439px) {
  .nav-link { padding-inline: var(--s-3); }
}

/* Below 1180 even that is not enough, so the wordmark goes and the mark
   stands alone rather than being cut in half. */
@media (min-width: 1080px) and (max-width: 1179px) {
  .brand-text { display: none; }
}

/* --- phones: the brand competes with six icon buttons ------------------- */

/* At 390 the tools are 252px of the 338px available. The wordmark cannot fit
   beside them at any size worth reading, so the mark carries the brand and
   gets its full 88px back. */
@media (max-width: 767px) {
  .brand-text { display: none; }
}

/* The header search icon is the one control that costs nothing to remove:
   the drawer it sits next to opens with a search field as its FIRST element,
   so search is still one tap away and is a real input rather than a jump to
   `shop#search`. */
@media (max-width: 420px) {
  .nav-search-btn { display: none; }
}

/* Small mobile. Interface sound is the least-reached control on the bar and
   the first that can go; the remaining four keep their 44px targets. */
@media (max-width: 360px) {
  .sound-btn { display: none; }
  .nav-tools { gap: 2px; }
}

/* ==========================================================================
   11. BREADCRUMBS — slightly larger, and told apart from their separators

   Asked for directly: the breadcrumb was too small to read. It was 11px mono
   uppercase with .06em tracking, which is the build's LABEL size — the same
   step as a card's category tag or a stat caption. A breadcrumb is not a
   label. It is navigation, it is the first line on the page, and on the
   product page it is the only thing naming the category you came from.

   Raised one step to 12.5px. Deliberately not more: at 14px, uppercase mono
   with this much tracking starts competing with the `<h1>` two lines below
   it, and the point of a breadcrumb is that it does not.

   Three things came with the size, because a bigger breadcrumb makes each of
   them more visible rather than less:

   1. THE SEPARATOR NOW READS AS A SEPARATOR. Every item was one colour and
      the chevron sat at .55 opacity between them, so the row read as five
      things of equal weight. Links are --fg-subtle, the chevron drops to
      .35, and the page you are actually on is --fg at 600 — an endpoint, not
      another link.
   2. THE CRUMBS ARE TAPPABLE. At 11px with no vertical padding the links
      were an 11px-tall target. They now carry padding and a hit area that
      clears the 24px WCAG 2.2 minimum without changing the visual rhythm.
   3. THE PRODUCT PAGE CANNOT WRAP TO THREE LINES. Its last crumb is the
      whole product name, generated in catalog.js — "Petrol Engine for
      Milking Machine 6.5 H.P." after "Home" and "Farm Machinery". At 320px
      that is three wrapped lines of uppercase mono sitting on top of an
      `<h1>` that says the same words. It truncates instead.
   ========================================================================== */
.breadcrumb {
  font-size: 12.5px;
  letter-spacing: .05em;
  column-gap: var(--s-3);
  row-gap: var(--s-1);
  align-items: center;
  margin-bottom: var(--s-6);
}

.breadcrumb a {
  color: var(--fg-subtle);
  padding-block: 3px;
  border-radius: 5px;
  transition: color var(--dur-1) var(--ease-out);
}
.breadcrumb a:hover { color: var(--brand); }
.breadcrumb a:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 3px;
  color: var(--brand);
}

/* The hit area is the pad, not the box: 3px of padding on a 12.5px line is
   about 19px, so a ::before takes it to 30 without moving anything. */
.breadcrumb a { position: relative; }
.breadcrumb a::before {
  content: '';
  position: absolute;
  inset: -6px -4px;
}

/* the page you are on — the end of the trail, not another step in it */
.breadcrumb > span:last-child {
  color: var(--fg);
  font-weight: 600;
}

.breadcrumb .ico {
  width: 14px;
  height: 14px;
  opacity: .35;
  flex: none;
}

/* The product page's last crumb is a whole product name. One line, and let
   the `<h1>` underneath carry the full title — it always does. */
@media (max-width: 720px) {
  .breadcrumb {
    flex-wrap: nowrap;
    font-size: 12px;
    column-gap: var(--s-2);
  }
  .breadcrumb a { white-space: nowrap; }
  .breadcrumb > span:last-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}

/* ==========================================================================
   12. A MACHINERY CARD STOPS THROWING ITS SPECS AWAY ON A PHONE

   `.spec-facts` is `white-space: nowrap` with an ellipsis, and on the
   two-column mobile grid the sweep measured it losing 112px of its own
   content — "6.5 H.P. · unit · 2 options" arriving as "6.5 H.P. · un…".

   Truncating a card TITLE is fine, because the product page repeats it. This
   is not a title: it is the horsepower, the unit and the number of variants,
   which is most of what someone deciding between two chaff cutters is
   actually reading, and it appears nowhere else on the card.

   So it wraps instead, clamped to two lines so a long fact list still cannot
   push the price out of the card.
   ========================================================================== */
@media (max-width: 700px) {
  .spec-facts {
    white-space: normal;
    text-overflow: clip;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    line-height: 1.35;
  }
}
