/* ==========================================================================
   Hiwa Saeed Yasin — PAGE-LEVEL BLOCKS
   ========================================================================== */

/* ==========================================================================
   Hero
   --------------------------------------------------------------------------
   Type on the left, photograph running off the right edge of the screen. The
   bleed is the point: a blanket is a continuous thing and cropping it inside a
   neat rectangle makes it look like a swatch. Below 900px it stacks and the
   photograph becomes an ordinary 3:2 block.
   ========================================================================== */

/* A LIGHT, LAYERED HERO.

   Warm cream ground, oversized headline, the photograph in a soft rounded
   frame, and small cards floating over its corners. The footer is still dark,
   but the top of the site opens light and airy instead of heavy.

   Two soft radial washes rather than a flat fill. They are what stops a large
   pale area reading as blank paper, and they are warm rather than grey, so the
   page still feels like a textile shop and not a clinic. */
.hero {
  position: relative;
  isolation: isolate;
  /* The stage already carries its own bottom padding for the floating card to
     hang into, so the section's own bottom padding stays modest — together
     they were leaving a dead band under the hero. */
  padding-block: clamp(2.5rem, 1.5rem + 4vw, 5rem) clamp(2rem, 1rem + 2.5vw, 3.5rem);
  /* Defined once in tokens.css and shared with .page-head, so the home page
     and every other page open on exactly the same ground. */
  background: var(--wash-open);
}

.hero__grid {
  display: grid;
  gap: var(--s-8) var(--s-7);
  align-items: center;
}

@media (min-width: 980px) {
  .hero__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
    gap: var(--s-8);
  }
}

.hero__copy { position: relative; z-index: 2; }

/* ---- The opening sequence -------------------------------------------------
   The hero is above the fold, so it cannot wait for a scroll to arrive and it
   must not wait for JavaScript either. This is pure CSS and runs the moment
   the page paints: the label, then the headline, then the sentence, then the
   buttons, then the photograph, about a tenth of a second apart.

   Reading order, in other words — the page assembles itself in the order a
   person would read it, which is why it feels calm rather than busy.

   animation-fill-mode: backwards is what holds each element at its start state
   during its own delay. Without it they would all flash into place first and
   then animate, which is worse than no animation at all.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .hero .eyebrow,
  .hero__title,
  .hero__lead,
  .hero__actions,
  .hero__media {
    animation: rise 900ms var(--ease-out) backwards;
  }

  .hero .eyebrow   { animation-delay:  60ms; }
  .hero__title     { animation-delay: 140ms; }
  .hero__lead      { animation-delay: 260ms; }
  .hero__actions   { animation-delay: 360ms; }
  /* The photograph comes in last and a touch slower — it is the largest thing
     moving, and matching the text's speed made it feel like it was falling. */
  .hero__media     { animation: rise 1100ms var(--ease-out) 440ms backwards; }
}

.hero__title {
  font-size: var(--fs-hero);
  line-height: var(--lh-tight);
  margin-block-end: var(--s-5);
}

/* One word of a headline set in brass. On the home page it falls on "weight",
   because that is the promise the whole shop is built on, and it lets the
   accent appear in the type rather than only in the furniture.

   A brass rule draws itself under the word as the page opens — the last beat
   of the entrance sequence, and the thing that says which word matters.

   Shared: the hero uses it and so does every page head. It is deliberately
   not called .hero__accent any more, because it is no longer the hero's. */
.accent {
  position: relative;
  color: var(--brass);
  font-style: italic;
}

/* Below the descender, not through it — at 0.06em the rule cut straight
   across the tail of the g in "weight". */
.accent::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  inset-block-end: -0.1em;
  height: 3px;
  background: var(--brass);
  opacity: 0.6;
  transform-origin: left;
}

@media (prefers-reduced-motion: no-preference) {
  .hero .accent::after {
    animation: draw-rule 700ms var(--ease-out) 900ms backwards;
  }
}

@keyframes draw-rule {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}


/* The hero once carried an interactive warmth picker, and the page a "How
   warm is it?" band below it. Both are gone, along with the warmth scale
   itself — it rated pieces on data nobody had. All of it is in the git
   history if the idea is ever wanted back with real numbers behind it. */

.hero__lead {
  font-size: var(--fs-lead);
  color: var(--fg-soft);
  max-width: 42ch;
  margin-block-end: var(--s-6);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}


/* ---- The stage ------------------------------------------------------------
   The photograph and the cards that sit on it. position: relative here is what
   the floating cards are positioned against — not the grid, so the cards
   travel with the picture at every width.
   -------------------------------------------------------------------------- */

.hero__stage {
  position: relative;
  z-index: 1;
}

/* A generous radius here and nowhere else on the site. The hero is the one
   place the design is allowed to soften; the 3px corners everywhere else are
   what keep it from looking like a consumer app. */
.hero__media {
  border-radius: 22px;
  box-shadow: 0 2px 6px rgba(42, 33, 28, 0.06),
              0 28px 60px rgba(42, 33, 28, 0.16);
}

/* Parallax. The custom property is written by boot.js and only ever read here,
   and the rule only applies once boot.js has added .hero-ready — which it does
   after the entrance animation has finished with the transform. Before that
   this rule does not exist and the two cannot fight. */
html.hero-ready .hero__media {
  transform: translate3d(0, var(--py, 0px), 0);
  will-change: transform;
}


/* ---- The floating cards ---------------------------------------------------
   Below 980px they simply stack under the photograph. Cards hanging off the
   corners of a picture need room on both sides to look deliberate, and on a
   phone there is none — overlapped there they would just cover the product.
   -------------------------------------------------------------------------- */

.hero__chip,
.hero__card {
  background: rgba(255, 253, 250, 0.94);
  border: 1px solid var(--rule);
  border-radius: 16px;
  box-shadow: 0 2px 4px rgba(42, 33, 28, 0.05),
              0 16px 40px rgba(42, 33, 28, 0.12);
  backdrop-filter: blur(8px);
}

.hero__chip {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-block-start: var(--s-4);
  padding: var(--s-3) var(--s-4);
  font-size: var(--fs-small);
  line-height: 1.3;
}

.hero__chip strong { display: block; color: var(--fg); }

.hero__chip-sub {
  display: block;
  font-size: var(--fs-micro);
  color: var(--fg-soft);
}

.hero__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--sage);
  flex-shrink: 0;
  box-shadow: 0 0 0 4px rgba(74, 107, 79, 0.16);
}

.hero__card {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  margin-block-start: var(--s-4);
  padding: var(--s-3) var(--s-4);
  text-decoration: none;
  color: var(--fg);
  transition: transform var(--t-med) var(--ease-out),
              border-color var(--t-fast) var(--ease);
}

.hero__card:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
}

/* Overlapped thumbnails. Negative inline margin on all but the first, so they
   tuck behind each other the way a handful of swatches would. */
.hero__thumbs {
  display: flex;
  flex-shrink: 0;
}

.hero__thumb {
  width: 46px;
  height: 46px;
  border-radius: 12px;
  overflow: hidden;
  border: 2px solid var(--cream-lift);
  background: var(--bg-sink);
  box-shadow: 0 2px 6px rgba(42, 33, 28, 0.14);
}

.hero__thumb + .hero__thumb { margin-inline-start: -16px; }

.hero__thumb img { width: 100%; height: 100%; object-fit: cover; }

.hero__card-text { line-height: 1.3; }
.hero__card-text strong { display: block; font-size: var(--fs-small); }

.hero__card-sub {
  display: block;
  font-size: var(--fs-micro);
  color: var(--fg-soft);
}

.hero__card-arrow {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-inline-start: auto;
  color: var(--accent-text);
  transition: transform var(--t-med) var(--ease-out);
}

.hero__card:hover .hero__card-arrow { transform: translateX(4px); }

@media (min-width: 980px) {
  /* Room at the bottom and the left for the cards to hang into. */
  .hero__stage { padding-block-end: var(--s-8); padding-inline-start: var(--s-6); }

  .hero__chip {
    position: absolute;
    inset-block-start: var(--s-5);
    inset-inline-end: calc(var(--s-5) * -1);
    margin: 0;
    z-index: 3;
  }

  /* Sized by its contents rather than to a fixed width — it is a row of
     thumbnails and two lines of text, and a set width would either crop the
     label or leave a gap after the arrow. */
  .hero__card {
    position: absolute;
    inset-block-end: 0;
    inset-inline-start: calc(var(--s-7) * -1);
    width: max-content;
    max-width: min(360px, 90%);
    margin: 0;
    z-index: 3;
  }
}


/* ==========================================================================
   Page head — the opening of every page that is not the homepage
   --------------------------------------------------------------------------
   This used to be a dark woven band, which meant the site opened light and
   airy on the home page and heavy everywhere else — two different websites
   sharing a header. It now speaks the hero's language: the same warm ground,
   the same oversized serif with one word in brass, the same staggered
   entrance, the same rhythm.

   What it does NOT take from the hero is the photograph and the cards
   floating off its corners. That composition works on the home page because
   nothing below it is competing; on the catalogue the same arrangement would
   push the product grid itself off the bottom of the screen, and the grid is
   the reason anyone opened that page. So the light, the type and the timing
   carry across, and the staging stays where it earns its place.
   ========================================================================== */

.page-head {
  position: relative;
  isolation: isolate;
  padding-block: clamp(2.75rem, 1.75rem + 4vw, 5rem) clamp(2.25rem, 1.5rem + 2.5vw, 3.5rem);
  background: var(--wash-open);
}

.page-head__inner { max-width: 48rem; }

.page-head__title {
  font-size: var(--fs-h1);
  line-height: var(--lh-tight);
  margin-block: var(--s-4) var(--s-5);
}

.page-head__lead {
  font-size: var(--fs-lead);
  color: var(--fg-soft);
  max-width: 52ch;
}

.page-head__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-block-start: var(--s-6);
}

/* ---- The slim variant, for the product page -------------------------------
   A product page's headline is the product's own name, and that belongs
   beside the photograph rather than in a banner above it. So this page opens
   on the same ground as every other one, but carries only the way back.
   -------------------------------------------------------------------------- */

.page-head--slim { padding-block: var(--s-5); }

.crumb {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-body);
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--accent-text);
  text-decoration: none;
}

.crumb svg {
  width: 1em;
  height: 1em;
  transition: transform var(--t-fast) var(--ease);
}

/* Toward the way out, which in a right-to-left reading is the other way —
   a logical property rather than a negative pixel value. */
.crumb:hover svg { transform: translateX(-3px); }

/* ---- The same opening sequence as the hero --------------------------------
   Pure CSS, so it runs the moment the page paints rather than waiting for
   JavaScript, and it cannot leave anything invisible if a script fails. The
   page assembles itself in the order a person reads it: label, headline,
   sentence, buttons.

   The delays are the hero's, shortened at the tail — a page head is three
   short elements rather than a headline plus a photograph, and holding the
   hero's full timing here made the page feel slow to settle.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .page-head .eyebrow,
  .page-head__title,
  .page-head__lead,
  .page-head__actions {
    animation: rise 800ms var(--ease-out) backwards;
  }

  .page-head .eyebrow   { animation-delay:  60ms; }
  .page-head__title     { animation-delay: 140ms; }
  .page-head__lead      { animation-delay: 240ms; }
  .page-head__actions   { animation-delay: 330ms; }

  .page-head .accent::after {
    animation: draw-rule 700ms var(--ease-out) 700ms backwards;
  }
}


/* ==========================================================================
   Why choose Hiwa
   --------------------------------------------------------------------------
   Five promises as cards on a warm ground.

   It was five thin columns separated by hairlines. That read as a footnote
   rather than a section: at a fifth of the container each column was about
   200px wide, which forced the headings down to body size and left the whole
   thing looking smaller than the claims it was making.

   Cards instead, three to a row with the last two centred beneath. Fewer,
   wider, and each one an object you can look at on its own.

   The one piece of real contrast is the icon badge: a filled espresso circle
   with a cream icon, sitting on a soft brass shape. Everything else in the
   section is warm and low-contrast, which is exactly what lets one small dark
   circle carry the whole card without shouting.

   THE MOTION, AND THE RULE IT FOLLOWS.
   Everything happens once, on the way in, and then the section is still.
   Nothing loops and nothing moves while it is being read.

   It runs off ONE observed element — the <ul> carries data-reveal-group,
   ui.js gives it .is-in, and every delay is an nth-child offset from that
   single moment, so the cards and their icons never drift apart.
   ========================================================================== */

/* ---- The ground -----------------------------------------------------------
   Two warm washes over a diagonal, which is what stops a large pale area from
   reading as blank paper. Warm rather than grey, so the band still feels like
   a shop selling cloth.
   -------------------------------------------------------------------------- */

.reasons-band {
  position: relative;
  isolation: isolate;
  background:
    radial-gradient(85% 70% at 10% 0%, rgba(176, 133, 66, 0.11) 0%, transparent 62%),
    radial-gradient(75% 70% at 94% 100%, rgba(160, 90, 70, 0.07) 0%, transparent 64%),
    linear-gradient(172deg, #F7F0E5 0%, var(--cream-sink) 48%, #EBE2D3 100%);
}


/* ---- The heading ----------------------------------------------------------
   Centred, with a line under it. The button that used to sit out to the right
   is now below the cards, because a centred heading with something pinned to
   one side of it is neither one thing nor the other.
   -------------------------------------------------------------------------- */

.reasons-head {
  max-width: 46rem;
  margin-inline: auto;
  margin-block-end: clamp(var(--s-7), 2rem + 2vw, var(--s-8));
  text-align: center;
}

.reasons-head__title {
  font-size: var(--fs-h2);
  line-height: var(--lh-heading);
  margin-block: var(--s-3) var(--s-4);
}

.reasons-head__sub {
  font-size: var(--fs-lead);
  color: var(--fg-soft);
  max-width: 40ch;
  margin-inline: auto;
}

/* "Hiwa" does two things once: a slow brass sweep left to right across the
   letterforms, then the rule drawing itself underneath after the sweep has
   passed. Both are keyed to the heading arriving, both play a single time.

   The sweep is a gradient clipped to the text. BOTH ends of that gradient are
   solid --brass and only the middle is bright, so the word is the right
   colour before the animation starts and after it finishes — if it never runs
   at all, nothing looks wrong. */

@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  @media (prefers-reduced-motion: no-preference) {
    .reasons-band .accent {
      background-image: linear-gradient(100deg,
        var(--brass) 0%, var(--brass) 40%,
        var(--brass-glow) 50%,
        var(--brass) 60%, var(--brass) 100%);
      background-size: 300% 100%;
      background-position: 100% 0;
      background-repeat: no-repeat;
      -webkit-background-clip: text;
      background-clip: text;
      color: transparent;
    }

    .reasons-head.is-in .accent {
      animation: brass-sweep 1500ms var(--ease-out) 260ms 1 both;
    }
  }
}

@keyframes brass-sweep {
  from { background-position: 100% 0; }
  to   { background-position: 0 0; }
}

@media (prefers-reduced-motion: no-preference) {
  html.is-loaded .reasons-head[data-observed] .accent::after {
    transform: scaleX(0);
    transition: transform 760ms var(--ease-out) 620ms;
  }
  html.is-loaded .reasons-head.is-in .accent::after { transform: scaleX(1); }
}


/* ---- The cards ------------------------------------------------------------
   Flex rather than grid, on purpose. Five items in a three-column grid leaves
   the last row hanging off to one side; flex-wrap with justify-content:center
   puts three on the first row and centres the remaining two under them, which
   is the only arrangement of five that does not look like a mistake.
   -------------------------------------------------------------------------- */

.reasons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(var(--s-4), 1rem + 0.8vw, var(--s-6));
  list-style: none;
  padding: 0;
  margin: 0;
}

.reason {
  position: relative;
  flex: 1 1 17rem;
  max-width: 23rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--s-3);
  padding: clamp(var(--s-6), 1.5rem + 1vw, var(--s-7)) var(--s-5)
           clamp(var(--s-6), 1.5rem + 1vw, var(--s-7));
  background: var(--cream-lift);
  /* Far softer than the site's 3px. A card this size with square corners
     reads as a table cell; the reference work this was drawn from is all
     generous radii, and it suits cloth. */
  border-radius: 18px;
  box-shadow: 0 1px 2px rgba(42, 33, 28, 0.04),
              0 12px 32px rgba(42, 33, 28, 0.07);
  transition: transform 520ms var(--ease-out),
              box-shadow 520ms var(--ease-out);
}

/* WHY THE ENTRANCE AND THE HOVER USE DIFFERENT PROPERTIES.

   Both want to move the card vertically, and if both wrote `transform` they
   would fight in two separate ways:

     1. Specificity. The entrance rules are guarded by html.is-loaded and
        [data-observed], which makes them far heavier than a plain .reason:hover
        — so the settled entrance state would simply win and hover would do
        nothing at all.
     2. Timing. A transition is governed by the properties of the state being
        transitioned TO. The settled state carries the stagger delay, so a
        hover would inherit it and take up to 400ms to begin.

   So the entrance animates `translate` and `scale` — the standalone transform
   properties — and hover animates `transform`. The browser composes them, and
   each keeps its own timing. The :where() wrappers below take the guards out
   of the specificity calculation entirely, which is belt and braces on top. */


/* ---- The badge ------------------------------------------------------------
   A filled espresso circle with a cream icon, over a soft brass shape. The
   shape is an asymmetric border-radius rather than a circle, so it reads as
   something organic sitting behind the badge instead of a second ring.
   -------------------------------------------------------------------------- */

.reason__mark {
  position: relative;
  display: grid;
  place-items: center;
  inline-size: clamp(3rem, 2.4rem + 1vw, 3.75rem);
  block-size:  clamp(3rem, 2.4rem + 1vw, 3.75rem);
  margin-block-end: var(--s-2);
  border-radius: 50%;
  background: var(--espresso);
  color: var(--cream);
  box-shadow: 0 4px 10px rgba(42, 33, 28, 0.18);
  transition: transform 520ms var(--ease-out),
              box-shadow 520ms var(--ease-out);
}

.reason__mark::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -42%;
  background: rgba(176, 133, 66, 0.16);
  /* An uneven radius on each corner — a soft blob rather than a halo. */
  border-radius: 46% 54% 52% 48% / 50% 44% 56% 50%;
  transition: transform 700ms var(--ease-out);
}

.reason__icon {
  display: block;
  inline-size: 45%;
  block-size: 45%;
  color: currentColor;
}

.reason__name {
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 1rem + 0.4vw, 1.4rem);
  line-height: var(--lh-heading);
}

.reason__note {
  font-size: clamp(0.9375rem, 0.88rem + 0.16vw, 1.0625rem);
  color: var(--fg-soft);
  max-width: 32ch;
  margin: 0;
}

/* The section had a "See the range" button under the cards. It was removed —
   the catalogue is already reachable from the header, the category tiles
   above and the footer, and a fourth route to the same page was just noise
   under a section whose job is to reassure rather than to route. */


/* ---- Hover ----------------------------------------------------------------
   The card rises a little and its shadow deepens; the badge lifts further and
   turns a few degrees, and the shape behind it swells slightly. A few degrees,
   not a spin — the point is that it feels picked up, not that it performs.

   Pointer devices only: on a phone :hover can stick after a tap and leave one
   card permanently raised.
   -------------------------------------------------------------------------- */

@media (hover: hover) {
  .reason:hover {
    transform: translateY(-6px);
    box-shadow: 0 2px 4px rgba(42, 33, 28, 0.05),
                0 22px 48px rgba(42, 33, 28, 0.13);
  }

  .reason:hover .reason__mark {
    transform: translateY(-3px) rotate(-5deg) scale(1.06);
    box-shadow: 0 8px 18px rgba(42, 33, 28, 0.24);
  }

  .reason:hover .reason__mark::before { transform: scale(1.14) rotate(8deg); }
}


/* ---- The entrance ----------------------------------------------------------
   Fade and rise, 100ms apart, on an ease-out curve so each card decelerates
   into place rather than arriving at a constant speed.

   [data-observed] gates all of it: it is only present once ui.js has taken
   charge of the element. With JavaScript off, or before boot, none of these
   rules match and the section is simply visible — the same principle .reveal
   follows in base.css.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {

  :where(html.is-loaded .reasons[data-observed]) .reason {
    opacity: 0;
    translate: 0 20px;
    /* The delay is read from --stagger rather than declared separately. It has
       to be: this rule uses the transition SHORTHAND, and a shorthand resets
       every part it does not mention — a separate transition-delay on a
       lower-specificity nth-child rule would be silently zeroed and all five
       would arrive at once. Inside the shorthand it survives, and it inherits,
       which is how the icon below picks up the same number.

       transform and box-shadow are listed here with no delay so that hover
       stays instant once the card has settled. */
    transition: opacity 700ms var(--ease-out) var(--stagger, 0ms),
                translate 700ms var(--ease-out) var(--stagger, 0ms),
                transform 520ms var(--ease-out),
                box-shadow 520ms var(--ease-out);
  }

  :where(html.is-loaded .reasons[data-observed].is-in) .reason {
    opacity: 1;
    translate: none;
  }

  /* The icon draws itself as its card arrives. pathLength="1" in the markup
     normalises every shape to a length of 1, so one dash rule covers all five
     icons whatever they are actually drawn from. */
  :where(html.is-loaded .reasons[data-observed]) .reason__icon > * {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    transition: stroke-dashoffset 900ms var(--ease-out)
                calc(var(--stagger, 0ms) + 220ms);
  }

  :where(html.is-loaded .reasons[data-observed].is-in) .reason__icon > * {
    stroke-dashoffset: 0;
  }

  /* The badge grows into the card rather than appearing at full size in it. */
  :where(html.is-loaded .reasons[data-observed]) .reason__mark {
    scale: 0.82;
    transition: scale 760ms var(--ease-out) calc(var(--stagger, 0ms) + 90ms),
                transform 520ms var(--ease-out),
                box-shadow 520ms var(--ease-out);
  }

  :where(html.is-loaded .reasons[data-observed].is-in) .reason__mark {
    scale: 1;
  }
}

/* ---- The stagger ------------------------------------------------------------
   One number per card, inherited by everything inside it, which is what keeps
   a card and its icon arriving as one event instead of two near-misses.

   100ms apart: fast enough that the group still reads as a single gesture,
   slow enough to see the order it happens in.
   ---------------------------------------------------------------------------- */

.reason:nth-child(1) { --stagger:   0ms; }
.reason:nth-child(2) { --stagger: 100ms; }
.reason:nth-child(3) { --stagger: 200ms; }
.reason:nth-child(4) { --stagger: 300ms; }
.reason:nth-child(5) { --stagger: 400ms; }

/* ==========================================================================
   Story band — the three-part "how it is made" strip
   ========================================================================== */

.story__item { border-block-start: 2px solid var(--accent); padding-block-start: var(--s-4); }

.story__title { margin-block-end: var(--s-3); }

.story__body { color: var(--fg-soft); }


/* ==========================================================================
   Visit the shop
   ========================================================================== */

.visit {
  display: grid;
  gap: var(--s-7);
  align-items: start;
}

@media (min-width: 900px) {
  .visit { grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr); gap: var(--s-8); }
}

/* The map is an iframe, which has no intrinsic ratio and will collapse to
   150px if it is not given one. */
.map {
  position: relative;
  aspect-ratio: var(--ratio-wide);
  overflow: hidden;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-md);
  background: var(--bg-sink);
}

.map iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.address { font-style: normal; color: var(--fg-soft); }
.address br { line-height: inherit; }


/* ==========================================================================
   Catalogue toolbar
   ========================================================================== */

.toolbar {
  padding-block: var(--s-5);
  border-block-end: 1px solid var(--rule);
}

.toolbar__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
}

/* .toolbar__controls, .toolbar__search and .toolbar__sort were removed with
   the search box and the "Order by" menu they laid out. The toolbar now holds
   only the category chips. */

.results-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  margin-block-end: var(--s-6);
}

.results-count {
  font-size: var(--fs-small);
  color: var(--fg-soft);
}


/* ==========================================================================
   Product detail
   ========================================================================== */

.product__cat {
  display: block;
  font-size: var(--fs-micro);
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  color: var(--accent-text);
  margin-block-end: var(--s-3);
}

.product__name { margin-block-end: var(--s-4); }

/* .product__ref, .product__desc and the enlarged warmth scale were here. The
   detail page no longer shows a reference code, a description or a warmth
   rating, because none of those were real. */

.product__buy { margin-block-start: var(--s-6); }

.product__hint {
  margin-block-start: var(--s-3);
  font-size: var(--fs-small);
  color: var(--fg-soft);
}


/* ==========================================================================
   Contact
   ========================================================================== */

.channels {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: 1fr;
}

@media (min-width: 640px) { .channels { grid-template-columns: repeat(2, 1fr); } }

.channel {
  display: flex;
  align-items: flex-start;
  gap: var(--s-4);
  padding: var(--s-5);
  background: var(--bg-lift);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  text-decoration: none;
  color: var(--fg);
  transition: border-color var(--t-fast) var(--ease),
              transform var(--t-med) var(--ease-out);
}

.channel:hover { border-color: var(--accent); transform: translateY(-2px); }

.channel__icon {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
  margin-block-start: 2px;
  color: var(--accent-text);
}

.channel__name {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: 700;
  line-height: 1.2;
}

.channel__value {
  display: block;
  margin-block-start: var(--s-1);
  font-size: var(--fs-small);
  color: var(--fg-soft);
  word-break: break-word;
}


/* ==========================================================================
   Closing contact band
   ========================================================================== */

.cta-band__inner {
  max-width: 640px;
  margin-inline: auto;
  text-align: center;
}

.cta-band__body {
  margin-block: var(--s-4) var(--s-6);
  color: var(--cream-soft);
}

.cta-band__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  justify-content: center;
}


/* ==========================================================================
   404
   ========================================================================== */

.error-page {
  display: grid;
  place-items: center;
  min-height: 62vh;
  text-align: center;
}

.error-page__mark {
  width: 72px;
  height: 72px;
  margin-inline: auto;
  margin-block-end: var(--s-5);
  color: var(--accent);
}
