/* DS-07 Split Stage -- Morrow Strand Salon, hair salon.
 *
 * Every contrast this stylesheet ships, measured at build time by
 * css.contrast() rather than asserted:
 *
 *   ink on the page ground             13.33:1
 *   ink on the raised plane            12.13:1
 *   ink in a form field                11.47:1
 *   muted text on the ground           7.06:1
 *   muted text on the plane            6.43:1
 *   link text on the ground            7.13:1
 *   link text on the plane             6.49:1
 *   secondary text on the ground       5.45:1
 *   white on the primary action fill   7.40:1
 *   white on the hovered action fill   9.17:1
 *   ink on the pale accent fill        9.32:1
 *   ink on the accent fill             5.68:1
 *   the focus ring on the ground       4.13:1
 *   the focus ring on the plane        3.76:1
 *   the ground reversed on the ink     13.33:1
 *   muted text on the ink rail         7.24:1
 *   the accent as text on the ink      5.68:1
 *
 * NO DEVIATION FROM SECTION 4'S PALETTE IS NEEDED, which is worth stating
 * because the three units before this one all needed one. Section 4 names the
 * focus ring as the highlight #62766D at 3px solid with 3px offset; measured
 * against the #F1ECE6 ground that is 4.13:1, over the 3:1 a non-text
 * indicator has to clear, so it is used exactly as written.
 *
 * The rest of the palette is used according to what it measures, and the
 * measurements are not symmetrical:
 *
 *   - The ACCENT #C9905A is 2.35:1 on the ground. It clears nothing
 *     there -- not text of any size, not a rule, not a ring. So on the cream
 *     it appears only as a FILL with ink on top (5.68:1), or thinned
 *     to #DFC3A7 as a pale plane (9.32:1). On the INK panel the order
 *     inverts and the accent reads as text at 5.68:1, which is where
 *     the footer and the rail use it.
 *   - The HIGHLIGHT #62766D is 4.13:1 on the ground: never normal text,
 *     always the focus ring, the section-marker rule and the hairlines.
 *   - Muted prose is mix(highlight, ink, .45) = #44514E at 7.06:1,
 *     which keeps the highlight's hue and moves only its luminance.
 *
 * THE SPLIT, which is the whole design and is therefore worth writing down.
 *
 * Section 2 asks for a 48/52 split viewport with a sticky stage on the left.
 * A design module has exactly two HTML hooks, so a single pane that outlives
 * one band cannot exist in this markup; every other band comes from the
 * shared renderer and its shape is fixed. What is built instead is a
 * PER-BAND split: at 1024 and up `.sec > .wrap` becomes a two-column grid,
 * the band's heading is moved into the 48% column and made sticky, and
 * everything after it stacks in the 52% column. The heading holds at the top
 * of the viewport while its own content scrolls past it and is released when
 * the band ends, which is the behaviour the section describes, band by band
 * rather than page-wide.
 *
 * Three things in that machinery are load-bearing and look arbitrary:
 *
 *   1. `row-gap: 0`. The stage spans `1 / span 30` so it covers every row the
 *      band will ever have. A row gap would then be multiplied by the
 *      twenty-nine empty implicit rows below the content and open a hole the
 *      height of the page. Spacing between the column-2 items is carried by
 *      margins instead, which a span cannot multiply. Empty implicit rows
 *      auto-size to zero, so the span itself costs nothing.
 *   2. `align-items: start`. A stretched grid item is exactly as tall as its
 *      area and has no room to stick. This is the difference between a sticky
 *      stage and a stage that does not move at all.
 *   3. `48% 52%` with NO column gap, the gap carried as padding INSIDE the
 *      right column. Both halves then stay expressible as a plain percentage
 *      of a known width, which is what makes every `sizes` attribute in this
 *      build a computable number instead of an estimate.
 *
 * Bands whose wrap has a single child -- the room figure, the review list,
 * the privacy body, the contact grid, the closing call to action -- have no
 * heading to put on the stage, so `:only-child` spans them across both
 * columns. Where that would make an image paint wider than its `sizes`
 * promises, pages.css pulls the band back into column 2 and draws the stage
 * as a pseudo-element instead.
 *
 * THE CONTENT BOX IS 1240px WIDE, NOT THE WRAP. Section 4 pins the content
 * max-width at 1240px and `box-sizing: border-box` is set globally, so a
 * plain `max-width: 1240px` with 48px of padding would give a 1240px box
 * with a 1144px interior and every `sizes` string in SIZES would be wrong by
 * ninety-six pixels. `.wrap` is capped at `--max + 2 * --gutter` so the
 * INTERIOR is 1240px exactly, and the cap is reached at a 1400px viewport:
 * 1240px + 96 gutters + 64 rail = 1400.
 */




:root {
  --bg: #F1ECE6;
  --ink: #1F2428;
  --act: #8C3B4A;
  --acc: #C9905A;
  --hi: #62766D;
  --plane: #E6E2DC;
  --field: #E0DCD7;
  --muted: #44514E;
  --act-t: #7C3845;
  --acc-t: #745A41;
  --acc-f: #DFC3A7;
  --act-h: #713542;
  --ink-m: #B2B0AD;
  --on-act: #FFFFFF;

  /* Section 4's spacing scale, entire. No length in this build is off it. */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 24px;
  --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px; --s10: 128px;

  --max: 1240px;         /* the CONTENT width, section 4 */
  --measure: 68ch;        /* section 4 */
  --measure-s: 52ch;      /* section 4, review quotations */
  --radius: 4px;          /* section 4, the only radius in the build */
  --rail: 64px;           /* section 4, the desktop edge header */
  --head-h:var(--catalog-font-heading);         /* section 4, the mobile top bar */
  --band-pad: 72px;       /* section 4's 72 / 112 / 144 section spacing */
  --gutter: 16px;
  --gap: var(--s5);       /* base.css reads this for every .grid */

  --hair: 1px;
  --rule: 2px;

  --font-h:var(--catalog-font-heading);
  --font-b:var(--catalog-font-body);

  /* Section 4: 220ms standard, 600ms maximum. */
  --t: 220ms cubic-bezier(.2,.8,.2,1);
  --t-long: 600ms cubic-bezier(.2,.8,.2,1);

  /* base.css draws :focus-visible from these three, so the ring is set by
     declaring them rather than by rewriting the rule. Section 4's values,
     unaltered -- see the palette note above for why no correction is due. */
  --focus-ring: #62766D;
  --focus-width: 3px;
  --focus-offset: 3px;
}

/* Section 7's gutter ladder, and the section spacing that steps with it. */
@media (min-width: 360px)  { :root { --gutter: 18px; } }
@media (min-width: 375px)  { :root { --gutter: 20px; } }
@media (min-width: 414px)  { :root { --gutter: 24px; } }
@media (min-width: 768px)  { :root { --gutter: 36px; --band-pad: 80px; } }
@media (min-width: 1024px) { :root { --gutter: 48px; --band-pad: 88px; } }

/* ---- the ground ------------------------------------------------------- */

body {
  background-color: var(--bg);
  color: var(--ink);
  font-family: var(--font-b);
  font-size: 1rem;
  line-height: 1.6;
}

@media (min-width: 768px) { body { font-size: 1.0625rem; } }

h1, h2, h3 {
  font-family: var(--font-h);
  font-weight: 400;
  margin: 0;
  overflow-wrap: break-word;
}

/* Section 4's mobile H1, then its desktop H1 at the 768 identity change. */
h1 {
  font-size: clamp(2.25rem, 11vw, 3.75rem);
  line-height: .98;
  letter-spacing: -.02em;
}

@media (min-width: 768px) {
  h1 {
    font-size: clamp(3.25rem, 7vw, 7rem);
    line-height: .94;
    letter-spacing: -.035em;
  }
}

h2 { font-size: clamp(2rem, 4vw, 4rem); line-height: 1.02; }
h3 { font-size: clamp(1.25rem, 2vw, 1.75rem); line-height: 1.15; }

p { margin: 0; }

.measure   { max-width: var(--measure); }
.measure-s { max-width: var(--measure-s); }

a { color: var(--act-t); text-underline-offset: .18em; }
a:hover { color: var(--ink); }

/* Section 4 puts the metadata floor at .8125rem and labels at .875rem. */
.nav__no, .price__q, .svc__fitlabel, .gal__no, .rev__no, .proc__no,
.how__no, .ft__legal, .hint, .field__opt, .sub-form__status,
.cform__status, .pv__date, .revp__by, .rev__by {
  font-size: .8125rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---- the band, and the 48/52 split ------------------------------------ */
/*
 * `overflow: clip` and not `hidden`: clip contains the section markers and
 * the rules that run to the band edge without creating a scroll container,
 * which `hidden` would -- and a scroll container between a sticky element and
 * the viewport is what silently turns a sticky stage into a static one.
 */

.sec {
  position: relative;
  overflow: clip;
  padding-block: var(--band-pad);
}

.wrap {
  width: 100%;
  max-width: calc(var(--max) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Below 1024 the band is one column and the spacing is plain margins. */
.sec > .wrap > * + * { margin-top: var(--s6); }

@media (min-width: 1024px) {
  .sec > .wrap {
    display: grid;
    grid-template-columns: 48% 52%;
    column-gap: 0;
    row-gap: 0;
    align-items: start;
  }

  .sec > .wrap > * {
    grid-column: 2;
    padding-left: var(--s7);
  }

  /* The heading IS the stage. */
  .sec > .wrap > h2,
  .sec > .wrap > .phead__h1,
  .sec > .wrap > .nf__h1 {
    grid-column: 1;
    grid-row: 1 / span 30;
    position: sticky;
    top: var(--s7);
    align-self: start;
    padding-left: 0;
    padding-right: var(--s5);
    margin-top: 0;
  }

  /* The first item in the 52% column sits level with the stage. */
  .sec > .wrap > h2 + *,
  .sec > .wrap > .phead__h1 + *,
  .sec > .wrap > .nf__h1 + * { margin-top: 0; }

  /* A band with one child has no heading to stage; -1 is safe because both
     columns are explicit. pages.css narrows this where an image is inside. */
  .sec > .wrap > :only-child {
    grid-column: 1 / -1;
    padding-left: 0;
  }
}

/* ---- the section marker ----------------------------------------------- */
/*
 * A rule and a filled square, drawn as pseudo-elements on the stage heading.
 * They are pseudo-elements and not markup because a class invented here and
 * emitted by nobody is a dead selector and the audit refuses it -- the module
 * has two HTML hooks and neither of them is a band heading.
 *
 * The rule is a structural divider, so it has to clear 3:1: it is the
 * highlight at 4.13:1. The square is decoration with nothing on it and
 * carries no requirement, but it is drawn in the action colour at
 * 6.30:1 anyway rather than in the accent, which clears nothing here.
 */

.sec > .wrap > h2::before,
.sec > .wrap > .phead__h1::before,
.sec > .wrap > .nf__h1::before {
  content: "";
  display: block;
  width: var(--s8);
  height: var(--rule);
  background: var(--hi);
  margin-bottom: var(--s4);
}

.sec > .wrap > h2::after,
.sec > .wrap > .phead__h1::after,
.sec > .wrap > .nf__h1::after {
  content: "";
  display: block;
  width: var(--s3);
  height: var(--s3);
  background: var(--act);
  margin-top: var(--s5);
}

/* ---- the vertical edge header ----------------------------------------- */
/*
 * One element in two states. Below 1024 it is an ordinary 56px top bar with
 * the shared <details> drawer; at 1024 and up it is fixed to the left edge,
 * 64px wide and the full height of the viewport, and the drawer is replaced
 * by the rail's own nine links. Section 7 puts that change at 1024 in as many
 * words: "desktop nav replaces disclosure".
 *
 * ROTATION, which is the one thing here that can quietly fail an audit.
 * measure2 reads every image's getBoundingClientRect and compares it against
 * what `sizes` promised, and a transform: rotate() on ANY ancestor of an
 * <img> inflates that rectangle. The rail rotates its wordmark, its nine
 * links and its Book control. NOT ONE OF THEM CONTAINS AN IMAGE, and nothing
 * else anywhere in this build is rotated at all.
 *
 * `writing-mode: vertical-rl` with `transform: rotate(180deg)` makes a label
 * read bottom-to-top. It is applied to each link rather than to the list, so
 * the nine keep their order down the rail instead of running backwards.
 */

.hd {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--ink);
  color: var(--bg);
}

/* A button carries its own pair and must not inherit the panel's link
   colour: `.hd a` is (0,1,1) and `.btn--book` is (0,1,0), so without the
   :not() the rail's link colour repainted the Book control's ink text in the
   page ground -- accent on accent-adjacent, 2.35:1 in the rail and 1.00:1 in
   the footer, twenty failures across ten pages and not one of them visible
   in the palette table, because the palette was never the thing that was
   wrong. */
.hd a:not(.btn) { color: var(--bg); }
.hd a:not(.btn):hover { color: var(--acc); }

.hd__in {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: var(--head-h);
  width: 100%;
  max-width: calc(var(--max) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.mark {
  font-family: var(--font-h);
  font-size: 1.125rem;
  line-height: 1.1;
  letter-spacing: -.01em;
  text-decoration: none;
  margin-right: auto;
  display: block;
}

.mark__h { margin-inline-end: var(--s2); }

.mark__sub {
  font-family: var(--font-b);
  font-size: .8125rem;
  letter-spacing: .10em;
  text-transform: uppercase;
  color: var(--ink-m);
}

.nav { display: none; }

.nav__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__link {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-width: 44px;
  min-height: 44px;
  text-decoration: none;
  font-size: .875rem;
}

.nav__link[aria-current="page"] { color: var(--acc); }

.nav__no { color: var(--ink-m); }

/* ---- the drawer, below 1024 ------------------------------------------- */

.drawer { margin-left: var(--s2); }

.drawer__toggle {
  display: flex;
  align-items: center;
  gap: var(--s2);
  min-height: 44px;
  min-width: 44px;
  padding-inline: var(--s2);
  cursor: pointer;
  list-style: none;
  font-size: .875rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.drawer__toggle::-webkit-details-marker { display: none; }

.drawer__bars {
  width: 20px;
  height: var(--rule);
  background: currentColor;
  box-shadow: 0 -6px 0 currentColor, 0 6px 0 currentColor;
}

.drawer[open] .drawer__bars { box-shadow: 0 6px 0 currentColor; }

.drawer__panel {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  background: var(--ink);
  border-top: var(--hair) solid var(--ink-m);
  padding: var(--s4) var(--gutter) var(--s6);
}

.drawer__panel nav { display: grid; }

.drawer__link {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: 44px;
  text-decoration: none;
  border-bottom: var(--hair) solid var(--ink-m);
}

.drawer__link:last-child { border-bottom: 0; }

.drawer__link[aria-current="page"] { color: var(--acc); }

/* ---- the rail, at 1024 and up ----------------------------------------- */

@media (min-width: 1024px) {
  body { padding-left: var(--rail); }

  .hd {
    position: fixed;
    inset: 0 auto 0 0;
    width: var(--rail);
    overflow-y: auto;
    overscroll-behavior: contain;
    border-right: var(--hair) solid var(--ink);
  }

  .hd__in {
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    gap: var(--s6);
    min-height: 100%;
    width: var(--rail);
    max-width: none;
    margin-inline: 0;
    padding-inline: 0;
    padding-block: var(--s4);
  }

  .mark {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    margin-right: 0;
    font-size: 1.25rem;
  }

  .nav { display: block; }

  .nav__list {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s5);
  }

  .nav__link {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    padding-block: var(--s2);
    letter-spacing: .04em;
  }

  /* The two-digit index is the drawer's affordance, not the rail's; it is
     hidden here rather than deleted, which would make it a dead selector. */
  .nav__link .nav__no { display: none; }

  .drawer { display: none; }
}

/* ---- actions ---------------------------------------------------------- */
/*
 * Logical padding throughout, because the Book control is horizontal in the
 * top bar and vertical in the rail and section 4's "24px minimum horizontal
 * padding on the primary action" means 24px ALONG the text in both.
 */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 44px;
  min-width: 44px;
  padding-inline: var(--s5);
  padding-block: var(--s3);
  border: 0;
  border-radius: var(--radius);
  font-family: var(--font-b);
  font-size: .9375rem;
  font-weight: 700;
  letter-spacing: .02em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--t), color var(--t);
}

.btn--primary, .btn--sub {
  background: var(--act);
  color: var(--on-act);
}

.btn--primary:hover, .btn--primary:active,
.btn--sub:hover, .btn--sub:active {
  background: var(--act-h);
  color: var(--on-act);
}

.btn--ghost {
  background: transparent;
  color: var(--act-t);
  box-shadow: inset 0 0 0 var(--rule) var(--hi);
}

.btn--ghost:hover, .btn--ghost:active {
  background: var(--plane);
  color: var(--ink);
}

.btn--book {
  background: var(--acc);
  color: var(--ink);
}

.btn--book:hover, .btn--book:active {
  background: var(--bg);
  color: var(--ink);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s4);
}

/* ---- the skip link ---------------------------------------------------- */

.skip {
  position: absolute;
  left: var(--s4);
  top: var(--s4);
  z-index: 50;
  background: var(--ink);
  color: var(--bg);
  padding: var(--s3) var(--s4);
  border-radius: var(--radius);
  text-decoration: none;
  transform: translateY(-220%);
}

.skip:focus, .skip:focus-visible { transform: translateY(0); }

/* ---- the subscribe band ----------------------------------------------- */

.sub-band {
  background: var(--ink);
  color: var(--bg);
  padding-block: var(--s9);
}

.sub-band a:not(.btn) { color: var(--acc); }

.sub-band__in {
  display: grid;
  gap: var(--s6);
}

@media (min-width: 1024px) {
  .sub-band__in {
    grid-template-columns: 48% 52%;
    column-gap: 0;
    align-items: start;
  }
  .sub-band__text { padding-right: var(--s5); }
  .sub-form { padding-left: var(--s7); }
}

.sub-band__h {
  font-size: clamp(1.75rem, 3.2vw, 3rem);
  line-height: 1.04;
}

.sub-band__p {
  margin-top: var(--s4);
  max-width: var(--measure);
  color: var(--ink-m);
}

.sub-form { display: grid; gap: var(--s4); justify-items: start; }

.sub-form__field { width: 100%; max-width: 420px; }

.sub-form__status { margin: 0; color: var(--ink-m); }

/* ---- forms ------------------------------------------------------------ */

.field label, .sub-band label {
  display: block;
  font-size: .875rem;
  line-height: 1.35;
  font-weight: 700;
  letter-spacing: .02em;
  margin-bottom: var(--s2);
}

.field input, .field select, .field textarea, .sub-band input {
  width: 100%;
  min-height: 44px;
  padding: var(--s3) var(--s4);
  border: 0;
  border-radius: var(--radius);
  background: var(--field);
  color: var(--ink);
  font: inherit;
  box-shadow: inset 0 0 0 var(--hair) var(--muted);
  transition: box-shadow var(--t);
}

.field textarea { min-height: 168px; resize: vertical; }

.field input:focus, .field select:focus, .field textarea:focus,
.sub-band input:focus { box-shadow: inset 0 0 0 var(--rule) var(--ink); }

.field input::placeholder, .field textarea::placeholder,
.sub-band input::placeholder { color: var(--muted); }

.field__opt { text-transform: none; letter-spacing: normal; }

.hint { margin-top: var(--s2); text-transform: none; letter-spacing: normal; }

.err { margin: var(--s2) 0 0; font-size: .875rem; color: var(--act-t); }

.sub-band .err { color: var(--acc); }

/* ---- the footer ------------------------------------------------------- */

.ft {
  background: var(--ink);
  color: var(--bg);
  padding-block: var(--s8) var(--s7);
}

.ft a:not(.btn) { color: var(--acc); }
.ft a:not(.btn):hover { color: var(--bg); }

.ft__in {
  display: grid;
  gap: var(--s7);
  margin-top: var(--s8);
}

@media (min-width: 768px) {
  .ft__in { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.ft__h {
  font-size: 1.125rem;
  line-height: 1.2;
  margin-bottom: var(--s4);
  padding-bottom: var(--s3);
  border-bottom: var(--hair) solid var(--ink-m);
}

.ft__addr { line-height: 1.9; }

.ft__hours { margin: 0; }

.ft__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s4);
  padding-block: var(--s2);
  border-bottom: var(--hair) solid var(--ink-m);
}

.ft__row:last-child { border-bottom: 0; }

.ft__row dt { font-weight: 700; min-width: 11ch; }

.ft__row dd { margin: 0; color: var(--ink-m); }

.ft__list { list-style: none; margin: 0; padding: 0; }

.ft__list li { border-bottom: var(--hair) solid var(--ink-m); }

.ft__list li:last-child { border-bottom: 0; }

.ft__list a {
  display: block;
  min-height: 44px;
  line-height: 44px;
  text-decoration: none;
}

.ft__foot {
  margin-top: var(--s7);
  padding-top: var(--s5);
  border-top: var(--hair) solid var(--ink-m);
  display: grid;
  gap: var(--s3);
}

.ft__legal { color: var(--ink-m); }

/* ---- print ------------------------------------------------------------ */
/*
 * base.css already hides .skip, .drawer and .sub-band in print. What it
 * cannot know is that this header is FIXED at 1024 and up, and a fixed
 * element reprints on every page. It is returned to the flow here.
 */

@media print {
  body { padding-left: 0; }
  .hd { position: static; width: auto; background: none; color: inherit; }
  .hd__in { flex-direction: row; width: auto; }
  .mark, .nav__link { writing-mode: horizontal-tb; transform: none; }
  .sec > .wrap { display: block; }
  .sec > .wrap > * { padding-left: 0; }
  .ft { background: none; color: inherit; }
}


/* PREMIUM REALISM PASS — DS01-09
+   One unmistakable signature per design; shared selectors only provide polish. */
footer, .ft { position: relative; overflow: hidden; isolation: isolate; }
footer::before, .ft::before { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: -1; background: radial-gradient(circle at 88% 12%, rgba(234,91,155,.12), transparent 38%), linear-gradient(110deg, transparent 0 58%, rgba(234,91,155,.12) 58% 59%, transparent 59%); }
footer a, .ft a { text-underline-offset: .28em; transition: color .2s ease, transform .2s ease; }
footer a:hover, footer a:focus-visible, .ft a:hover, .ft a:focus-visible { color: #EA5B9B; }
.stf, .stf__card { transition: transform .28s ease, box-shadow .28s ease, border-color .28s ease; }
.stf:hover, .stf__card:hover { transform: translateX(5px); border-color: #EA5B9B; box-shadow: 0 18px 48px rgba(234,91,155,.12); }
.field--intake { padding: 14px; border-inline-start: 3px solid #EA5B9B; background: rgba(234,91,155,.12); }
.field--intake label { font-weight: 700; }
@media (prefers-reduced-motion: reduce) { .stf, .stf__card { transition: none; } .stf:hover, .stf__card:hover { transform: none; } }
