/* ============================================================
   MUTĖ MILLINERY — layout
   Containers, section rhythm, grids, responsive behaviour.
   Nothing else. Skin — colour on type, borders-as-decoration,
   hovers, the ornament placement — lives in components.css;
   motion lives in motion.css. Both load after this file, so
   every rule here is a structural default they may legitimately
   override.

   Rules of the road:
     · Baroque composes on an axis. Where lamaa goes asymmetric
       and editorial, this page centres or stacks square. The
       drama comes from light and scale, not from the grid.
     · One ground per band, and the bands are the only thing
       that changes colour. Panels are components' problem.
     · Zero horizontal overflow from 320px to 2560px. Every fr
       is minmax(0, 1fr) — bare 1fr has a min-content floor and
       is the commonest cause of a grid pushing the page wide.

   Breakpoint ladder (mobile-first, all min-width unless noted):
     560   footer goes two-up
     640   collection goes two-up
     700   the form grid splits
     900   footer goes four-up, occasions goes to one row
     1080  collection goes three-up
     1200  the last of the air
   ============================================================ */


/* ==== LAYOUT PRIMITIVES ==================================== */

:root {
  /* Distance from the viewport edge to the CONTAINER'S inner
     edge. The 100% inside resolves at the point of use, so this
     is only ever read on full-bleed boxes whose containing block
     is the page width (.hero, .section, .foot). Below --container
     it collapses cleanly to the gutter. */
  --rail: calc(max(0px, (100% - var(--container)) / 2) + var(--gutter));

  /* Air between a section head and the body it introduces. */
  --head-gap: clamp(var(--sp-5), 6vw, var(--sp-7));

  /* Column gap inside dense blocks. --gutter reaches 5rem at
     full width, which is right between a page edge and text and
     far too much between two form fields. */
  --gap-inner: clamp(var(--sp-3), 2.6vw, var(--sp-5));
}

/* The only container. Everything sits inside one. */
.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
  position: relative;
}


/* ==== SECTION RHYTHM & GROUNDS =============================
   The grounds are a contract shared with the other two sheets:
   change one here and the page fights itself. Stated explicitly
   on every band — including the ones that match <body> — so the
   scheme is legible in one place rather than inferred.
   ============================================================ */

.section {
  position: relative;
  padding-block: var(--section-y);
}

.section--collection,
.section--occasions,
.section--enquire,
.section--faq,
.section--atelier   { background: var(--pitch); }

.section--words     { background: var(--pitch-raised); }


/* ---- Section head ------------------------------------------
   A plain stack: eyebrow, title, deck. No 12-column split — the
   display type is enormous and a two-column head would make it
   look like it was hiding from something.
   ------------------------------------------------------------ */

.section__head {
  position: relative;
  margin-bottom: var(--head-gap);
}

.section__head .eyebrow { margin-bottom: var(--sp-3); }

.section__head .deck {
  margin-top: var(--sp-4);
  max-width: var(--measure);
}

/* The centred variant, used on the Two Ways band where the
   eyebrow carries a dash on each side. */
.section__head--centred { text-align: center; }

.section__head--centred .section__title { margin-inline: auto; }

.section__head--centred .deck {
  margin-inline: auto;
  max-width: var(--measure-tight);
}

@media (min-width: 900px) {
  .section__head .eyebrow { margin-bottom: var(--sp-4); }
  .section__head .deck    { margin-top: var(--sp-5); }
}


/* ==== HERO =================================================
   Bottom-lit and left-aligned: the eyebrow leads with a single
   dash, so there is no axis to centre on. Almost-full-height,
   with the display type allowed to run to 12vw.
   ============================================================ */

.hero {
  position: relative;
  background: var(--pitch);
  min-height: 100vh;      /* fallback for anything without svh */
  min-height: 100svh;     /* the real viewport on mobile, minus
                             the browser chrome that comes and goes */
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-top: calc(var(--nav-h) + var(--sp-5));
  padding-bottom: clamp(var(--sp-6), 12vh, var(--sp-8));
  /* Guard rail for 12vw display type and the italic's negative
     optical inset. `clip` rather than `hidden` so no scroll
     container is created. */
  overflow-x: clip;
}

/* .wrap-like, but the hero does not use .wrap — it needs the
   inner box to be a flex child that can grow. */
.hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.hero__title {
  margin-top: clamp(var(--sp-3), 3vh, var(--sp-5));
}

/* Each line is its own block so motion.css can lift them
   independently. line-height under 1 on Cormorant at this size
   is not tight — the font's own leading is generous. */
.hero__line {
  display: block;
  font-family: var(--font-display);
  font-size: var(--t-hero);
  font-weight: 300;
  line-height: 0.86;
  letter-spacing: var(--track-hero);
}

/* Cormorant's italic leans about 12° and its sidebearings are
   cut for text sizes, not for 11rem. Left edge pulled back so
   "Millinery" hangs on the same optical margin as "Mutė"
   above it; a hair of extra leading so the ascenders of the
   italic do not crowd the roman.

   -0.045em can never exceed the 20px minimum gutter: at the
   3.75rem floor it is 2.7px, at the 11rem ceiling 7.9px, and
   the gutter has grown to 80px long before then. */
.hero__line--it {
  margin-left: -0.045em;
  margin-top: 0.02em;
}

.hero__line--it em { font-style: italic; }

.hero__deck {
  margin-top: clamp(var(--sp-3), 3vh, var(--sp-4));
  max-width: var(--measure-tight);
}

/* ---- Actions: a row that becomes a column ------------------ */

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-top: clamp(var(--sp-4), 4vh, var(--sp-5));
}

/* Below this the two labels — "Commission a piece" / "Hire for
   an occasion" — cannot sit side by side without wrapping to
   two lines each, which looks like a mistake rather than a
   choice. Stack them full-width instead. */
@media (max-width: 479.98px) {
  .hero__actions {
    flex-direction: column;
    align-items: stretch;
    gap: var(--sp-2);
  }
}

.hero__aside {
  margin-top: clamp(var(--sp-3), 3vh, var(--sp-4));
  max-width: var(--measure-tight);
}

/* ---- Scroll cue -------------------------------------------
   Pinned to the container's inner right edge — the hero content
   runs left, so the cue balances the band rather than sitting
   under the type. --rail resolves against .hero, which is
   full-bleed, so it lands exactly on the container edge.
   ------------------------------------------------------------ */

.hero__scroll {
  position: absolute;
  right: var(--rail);
  bottom: clamp(var(--sp-3), 4vh, var(--sp-5));
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
}

.hero__scroll-rail {
  display: block;
  width: 1px;
  height: clamp(2.5rem, 7vh, 4.5rem);
  background: var(--gilt-dim);
}

/* The word runs DOWN the rail rather than sitting under it, so the
   pair reads as one continuous vertical line instead of a stray
   caption. The trailing letter-space that vertical-rl leaves at the
   foot is trimmed off with a negative margin. */
.hero__scroll-word {
  writing-mode: vertical-rl;
  font-size: var(--t-micro);
  font-weight: 300;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: var(--track-label);
  color: var(--parchment-faint);
  margin-block-end: calc(var(--track-label) * -1);
  -webkit-user-select: none;
          user-select: none;
}

/* Nothing to scroll toward on a short or landscape viewport,
   and it would collide with the actions. */
@media (max-height: 700px) {
  .hero__scroll { display: none; }
}


/* ==== GRIDS ================================================ */

.grid {
  display: grid;
  min-width: 0;
}

/* ---- The collection: six plates ---------------------------
   1 → 2 → 3. Explicit breakpoints rather than auto-fit: six
   items over three columns is two clean rows, and auto-fit
   would give a 4+2 orphan on wide displays.
   ------------------------------------------------------------ */

.grid--collection {
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(var(--sp-5), 5vw, var(--sp-7)) var(--gap-inner);
}

@media (min-width: 640px) {
  .grid--collection { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 1080px) {
  .grid--collection { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---- A plate ----------------------------------------------
   Flex column so the actions can be pushed to the bottom edge
   regardless of how long the note runs. The notes differ by two
   lines across the six, and a ragged row of buttons is the
   first thing the eye catches.
   ------------------------------------------------------------ */

.plate {
  position: relative;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* Containing block for the four corner brackets, which
   components.css positions absolutely. The ratio is stated here
   so that swapping the silhouette for a photograph (the SWAP
   note in the markup) changes nothing structural. */
.plate__frame {
  position: relative;
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  padding: var(--sp-4);
  overflow: hidden;
}

.plate__body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  padding-top: var(--sp-3);
}

.plate__name  { margin-top: 0.15rem; }
.plate__note  { margin-top: var(--sp-2); max-width: 40ch; }

.plate__prices {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-3);
  padding-top: var(--sp-3);
}

.price {
  display: grid;
  gap: 0.15rem;
  min-width: 0;
}

/* Pinned to the foot of the plate. The two buttons share the
   row evenly and wrap to full width when there is no room. */
.plate__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: auto;
  padding-top: var(--sp-4);
}

.plate__actions > .btn { flex: 1 1 8rem; }



/* ==== ATELIER =================================================
   Used to be a full-bleed inverted paper band. That reads as a
   flashbang scrolling down from a page that is dark everywhere
   else, so it now sits on the standard `--pitch` ground like
   every other section — no re-stated type colours, no special
   z-index to paint over `.grain`/`.vignette` (that was only ever
   needed to cover an opaque light section). The four-step process
   that used to live here is gone too; the section is just the
   opening statement and the materials list now.
   ============================================================ */

/* ---- Materials: a wrapping inline list -------------------- */

.materials {
  margin-top: clamp(var(--sp-5), 7vw, var(--sp-7));
  padding-top: var(--sp-4);
  border-top: 1px solid var(--pitch-line);
}

.materials__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-3);
}

.materials__item { min-width: 0; }


/* ==== OCCASIONS ============================================
   An index, not a card grid. Five rows separated by hairlines,
   each one: numeral · name · note · tag. On mobile the four
   parts stack under the numeral; from 900px they become one
   line of the ledger.
   ============================================================ */

.occ {
  display: grid;
  border-bottom: 1px solid var(--pitch-line);
}

.occ__row {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr);
  column-gap: var(--sp-3);
  row-gap: var(--sp-2);
  align-items: start;
  padding-block: clamp(var(--sp-3), 3.5vw, var(--sp-5));
  border-top: 1px solid var(--pitch-line);
}

.occ__num  { grid-column: 1; grid-row: 1; line-height: 1.4; }
.occ__name { grid-column: 2; grid-row: 1; }
.occ__note { grid-column: 2; grid-row: 2; max-width: var(--measure); }
.occ__tag  { grid-column: 2; grid-row: 3; justify-self: start; }

@media (min-width: 900px) {
  /* numeral | name | note | tag, on one baseline. The tag column
     is fixed so the right edge of the ledger stays true down the
     five rows whatever the tag says. */
  .occ__row {
    grid-template-columns:
      3.5rem
      minmax(0, 3.4fr)
      minmax(0, 7fr)
      minmax(0, 2.6fr);
    column-gap: var(--gap-inner);
    row-gap: 0;
    align-items: baseline;
  }

  .occ__num  { grid-column: 1; grid-row: 1; }
  .occ__name { grid-column: 2; grid-row: 1; }
  .occ__note { grid-column: 3; grid-row: 1; max-width: var(--measure); }
  .occ__tag  { grid-column: 4; grid-row: 1; justify-self: end; text-align: right; }
}

@media (min-width: 1200px) {
  .occ__row { column-gap: var(--gutter); }
}


/* ==== WORDS — ONE QUOTE AT A TIME ===========================
   Used to be a large testimonial with a drop cap plus two small
   ones underneath. Replaced with a single rotating quote: reads
   calmer, and it no longer gets longer every time a review is
   added.

   `.quote-carousel__track` stacks all three `<figure class="quote">`
   panels in the SAME grid cell (every direct child of a grid
   container with one implicit row/column lands in cell 1/1 unless
   told otherwise) — the track's height becomes whichever quote is
   tallest, with no JS measuring and no layout jump on crossfade.
   components.css handles which one is visible.
   ============================================================ */

.quote-carousel {
  max-width: 52ch;
  margin-inline: auto;
}

.quote-carousel__track {
  display: grid;
}

.quote-carousel__track > .quote {
  grid-area: 1 / 1;
  min-width: 0;
}

.quote__body { margin: 0; min-width: 0; }

.quote__text { position: relative; }

.quote__by { margin-top: var(--sp-4); }

.quote-carousel__dots {
  display: flex;
  justify-content: center;
  gap: var(--sp-2);
  margin-top: clamp(var(--sp-5), 6vw, var(--sp-6));
}


/* ==== ENQUIRE ==============================================
   One well, four corner brackets, and a form whose second half
   changes with the mode radios. Layout sets the skeleton; the
   pane visibility rule is components.css's and is CSS-only.
   ============================================================ */

.form-well {
  position: relative;      /* containing block for the corners */
  padding: clamp(var(--sp-4), 5vw, var(--sp-7));
}

/* ---- Mode switch ------------------------------------------
   Two equal columns, always — even at 320px. The sliding
   .mode__thumb is a 50%-wide absolute child that components.css
   moves with translateX(100%), and that arithmetic only holds
   while the track stays two even columns. Do not collapse this
   to one column at any width.
   ------------------------------------------------------------ */

.mode__legend { margin-bottom: var(--sp-2); }

.mode {
  position: relative;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-bottom: var(--sp-6);
}

.mode__opt {
  position: relative;
  z-index: 1;              /* above .mode__thumb */
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  padding: var(--sp-3);
  cursor: pointer;
  text-align: center;
}

/* ---- Field grid -------------------------------------------
   One column, two from 700px. --gap-inner rather than --gutter:
   a 5rem trench between two inputs looks like a broken form.
   ------------------------------------------------------------ */

.form__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: var(--gap-inner);
  row-gap: var(--sp-4);
}

.field--wide { grid-column: 1 / -1; }

@media (min-width: 700px) {
  .form__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 0;
}

.field__hint,
.field__error { max-width: var(--measure); }

/* The one checkbox row: box, then a label that wraps under
   itself rather than under the box. */
.field--check {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--sp-2);
  row-gap: 0.4rem;
  align-items: start;
}

.field--check .check__input  { grid-column: 1; grid-row: 1; }
.field--check .check__label  { grid-column: 2; grid-row: 1; }
.field--check .field__error  { grid-column: 1 / -1; }

/* ---- Vertical rhythm of the form --------------------------
   Margins rather than a grid gap: the two mode radios are the
   form's first children and are .sr-only (position:absolute), so
   they contribute no track — but the panes DO come and go via
   display:none, and margins collapse away with them where a
   grid gap would leave a hole.
   ------------------------------------------------------------ */

.form__pane { margin-top: var(--sp-6); }

.form__pane-label { margin-bottom: var(--sp-3); }

/* The shared "Anything else" field, a direct child of the form
   rather than of a grid. */
.form > .field--wide { margin-top: var(--sp-5); }

.form__foot {
  display: grid;
  justify-items: start;
  gap: var(--sp-3);
  margin-top: var(--sp-6);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--gilt-ghost);
}

.form__summary,
.form__fine { max-width: var(--measure); }

/* NOTE: no `display` is declared on .form__done. It carries the
   `hidden` attribute in the markup, and an author display value
   would defeat it — the confirmation would be on screen from
   first paint. Same reason the drawer gets none. */
.form__done       { max-width: var(--measure); }
.form__done-title { margin-top: var(--sp-3); }
.form__done-body  { margin-top: var(--sp-3); }
.form__done .btn  { margin-top: var(--sp-4); }


/* ==== FAQ ==================================================
   Native <details>, hairline-separated, held to a reading
   measure. The summary marker is suppressed here because it is
   structural — the caret in .faq__icon replaces it.
   ============================================================ */

.faq {
  max-width: 76ch;
  border-bottom: 1px solid var(--pitch-line);
}

.faq__item { border-top: 1px solid var(--pitch-line); }

.faq__q {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
  padding-block: var(--sp-3);
  cursor: pointer;
  list-style: none;
}

.faq__q::-webkit-details-marker { display: none; }

.faq__icon { flex: none; }

.faq__a {
  padding-bottom: var(--sp-4);
  max-width: var(--measure);
}


/* ==== FOOTER ===============================================
   The deepest ground on the page, and the second home of .gild
   — the wordmark repeats the hero's move as a sign-off.
   ============================================================ */

.foot {
  position: relative;
  background: var(--pitch-deep);
  padding-block: clamp(var(--sp-6), 9vw, var(--sp-8)) var(--sp-4);
  overflow-x: clip;      /* guards the oversized wordmark */
  text-align: center;
}

.foot__word { margin-top: var(--sp-4); }
.foot__line { margin-top: var(--sp-2); }

/* ---- Columns: 1 → 2 → 4 ----------------------------------- */

.foot__cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-5) var(--gap-inner);
  margin-top: clamp(var(--sp-6), 8vw, var(--sp-7));
  padding-top: var(--sp-5);
  border-top: 1px solid var(--pitch-line);
  text-align: left;
}

.foot__col { min-width: 0; }

.foot__list {
  display: grid;
  gap: 0.55rem;
  margin-top: var(--sp-3);
}

@media (min-width: 560px) {
  .foot__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (min-width: 900px) {
  .foot__cols {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    column-gap: var(--gutter);
  }
}

.foot__base {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-4);
  margin-top: clamp(var(--sp-5), 7vw, var(--sp-7));
  padding-top: var(--sp-3);
  border-top: 1px solid var(--pitch-line);
  text-align: left;
}


/* ==== SHARED PLACEMENT HELPERS =============================
   Structural containing blocks for children that other sheets
   position absolutely. Declared once, here, so components.css
   never has to remember to add position:relative alongside a
   colour rule.
   ============================================================ */

/* Every .btn in the markup carries a .btn__sweep — an absolutely
   positioned pane that motion.css rakes across the face. The
   button must clip it and must be its containing block. */
.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  text-align: center;
}

.btn__sweep {
  position: absolute;
  inset: 0;
  pointer-events: none;
}


/* ==== OVERFLOW GUARDS ======================================
   The page has three genuine overflow risks: 12vw display type,
   long unbroken strings (an email address, a URL), and the
   negative optical inset on the hero's italic line. The first
   and third are clipped at .hero; these are the rest.
   ============================================================ */

/* Addresses and mailto links are the only unbreakable strings
   in the markup, and they live in a footer column that is a
   quarter of the page at 900px. */
.foot__list,
.drawer__foot { overflow-wrap: break-word; }

/* The display type is the widest thing on the page and the
   headings are author-set, so a future copy change is the real
   risk here rather than the current words. Breaking inside a
   word is ugly; a page that scrolls sideways is worse. */
.section__title,
.hero__line { overflow-wrap: break-word; }


/* ==== NARROW-WIDTH REFINEMENTS =============================
   Below 400px the gutter is at its 1.25rem floor and every
   fixed column has to give something back.
   ============================================================ */

@media (max-width: 399.98px) {
  /* A four-character numeral column at 2.75rem leaves 240px for
     the name at 320px. 2.25rem buys back most of a word. */
  .occ__row {
    grid-template-columns: 2.25rem minmax(0, 1fr);
    column-gap: var(--sp-2);
  }

  /* Squarer, so the silhouette does not shrink to a token at
     the narrowest width. */
  .plate__frame {
    aspect-ratio: 1 / 1;
    padding: var(--sp-3);
  }

  .form-well  { padding: var(--sp-4) var(--sp-3); }
  .mode__opt  { padding: var(--sp-2); }
}


/* ==== WIDE-WIDTH REFINEMENTS ===============================
   Past --container the page stops growing and only the air
   between things does.
   ============================================================ */

@media (min-width: 1200px) {
  .grid--collection { column-gap: var(--gutter); }

  /* The reading measure widens a touch once the display type
     has stopped climbing. */
  .plate__note      { max-width: 44ch; }
}
