/* ============================================================
   Cascade — mobile layer.

   Enqueued LAST, after the per-page bundle, so it wins without
   editing the 44 near-identical page bundles (32 of which are
   byte-for-byte copies of one another — see assets/css/studio.css
   and its clones). Everything here is a phone/touch correction to
   the shared design, not a new design: same tokens, same type
   scale, same rhythm.

   Measured on cascade.local at 320 / 390 / 768 CSS px with mobile
   emulation before and after. Findings this file answers:

     - the hamburger — the only way to reach the menu on a phone —
       was a 32x32 target
     - the menu could not be closed with Escape or a tap outside,
       and in landscape its last link fell below the fold inside a
       sticky header, so it was unreachable
     - 125 photo captions rendered at 9.6px, and the booking sheet's
       labels at 9.6-10.6px
     - 345 footer links at 34px tall, breadcrumbs at 16px, filter
       chips at 35px
     - every panel that inverts on :hover (.tile, .feat, .value,
       .ptile, .pcard, .scard, .pillar, .tb-row) stayed inverted
       after a tap on a touch screen
     - nothing accounted for the home indicator or a notch

   Horizontal overflow was already clean at every width tested;
   nothing here is a layout rescue.
   ============================================================ */

/* --- Let iOS keep the type scale it was given ---------------- */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;}

/* Long Utah place names ("Saratoga Springs", "Washington County")
   set at clamp(2.7rem,6vw,4.75rem) have very little room at 320px.
   Nothing overflows today; this is the guard so nothing does. */
h1,h2,h3,.vlabel,.nm,.tb-city{overflow-wrap:break-word;}

/* A tap should acknowledge itself in brand colour, not the default
   blue plate — especially now that :hover no longer fires. */
a,button,summary,label,.tile,.feat,.value,.ptile,.pcard,.scard,.pillar,.tb-row{
  -webkit-tap-highlight-color:rgba(189,63,36,.14);
}

/* Skip link: left:-9999px puts a real box 9999px off-canvas. The
   clip pattern keeps it out of the flow entirely. */
.skip{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;left:auto;}
.skip:focus{position:fixed;width:auto;height:auto;margin:0;overflow:visible;
  clip:auto;clip-path:none;white-space:normal;left:1rem;top:1rem;
  padding:.75rem 1.1rem;background:var(--granite);color:var(--bone);
  z-index:100;border-radius:var(--radius,2px);}

/* ============================================================
   1. THE MOBILE MENU
   ------------------------------------------------------------
   Below 1024px the hamburger is the entire navigation, so it is
   treated as such: a 46px target, a panel that hangs off the nav
   instead of pushing the page down, and a panel that can scroll
   when the viewport is short.
   ============================================================ */

@media (max-width:1024px){
  header.nav .menu-btn{
    display:inline-flex;align-items:center;justify-content:center;
    width:46px;height:46px;margin-right:-.5rem;   /* optical: keeps the
      glyph on the same line as the wrap padding while the box grows */
    flex-shrink:0;border-radius:var(--radius,2px);
  }
  header.nav .brand{min-height:44px;align-items:center;}

  /* The panel used to sit in the header's flow: opening it grew the
     sticky header from 70px to 402px and shoved the page down by
     that much. Hung off the bottom of the bar instead, the page
     underneath does not move. */
  header.nav .mobile-menu{
    display:none;
    position:absolute;left:0;right:0;top:100%;
    background:var(--bone);
    border-top:1px solid var(--rule);
    border-bottom:1px solid var(--rule);
    box-shadow:0 18px 40px -24px rgba(26,26,26,.45);
    /* Landscape on a phone is ~375-390px tall. The panel is 331px
       plus a 70px bar, so the last link ("Call the studio") fell
       off the bottom of a sticky header and could not be scrolled
       to. dvh tracks the browser chrome as it hides. */
    max-height:calc(100vh - 70px);
    max-height:calc(100dvh - 70px);
    overflow-y:auto;overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch;
    padding-bottom:env(safe-area-inset-bottom);
  }
  header.nav .mobile-menu.is-open{display:block;}
  header.nav .mobile-menu a{
    display:flex;align-items:center;min-height:52px;
    padding:.85rem var(--pad);border-bottom:1px solid var(--rule);
  }
  header.nav .mobile-menu a:last-child{border-bottom:0;}
  header.nav .mobile-menu a.active{color:var(--ember);font-weight:600;}
}

/* Rotating a tablet past the breakpoint with the menu open would
   otherwise leave the panel hanging under the desktop nav. */
@media (min-width:1025px){
  header.nav .mobile-menu,header.nav .mobile-menu.is-open{display:none;}
}

/* ============================================================
   2. TEXT THAT WAS TOO SMALL TO READ ON A PHONE
   ------------------------------------------------------------
   The micro-labels are the design's voice — mono, uppercase,
   widely tracked — so they stay small; they just stop going under
   ~12px, which is where they become decoration rather than text.
   Tracking is pulled in to buy back the width the larger size
   costs, so the captions still sit on one line wherever they did.
   ============================================================ */

@media (max-width:720px){
  /* Photo captions: .68rem site-wide, cut to .6rem (9.6px) below
     520px. 12px with tighter tracking occupies almost the same
     width as 9.6px did at .12em. */
  .ph-tag,.photoslot.has-photo .ph-tag{
    font-size:.75rem;letter-spacing:.05em;line-height:1.35;
    max-width:calc(100% - 1.7rem);
  }
  /* The longest captions ("Fig. 03 — Standing in the kitchen
     footprint") do reach a second line at 320-390px. Kept to a
     chip shape so a two-line caption still reads as a margin note
     and not a banner. */
  .photoslot.has-photo .ph-tag{padding:.34rem .6rem;align-items:flex-start;}
  .photoslot.has-photo .ph-tag::before{margin-top:.34em;}

  .eyebrow{font-size:.78rem;letter-spacing:.18em;}
  /* The quote's "Why the numbers move" label. Written long-hand because
     the bundles set it as `.casestudy .tag`, which outranks `p.tag`. */
  .casestudy .tag{font-size:.78rem;letter-spacing:.14em;}
  .foot-col h4{font-size:.78rem;}
  .post .ptag{font-size:.78rem;}

  /* The booking sheet's drawing-block labels. */
  .sheet-no{font-size:.72rem;letter-spacing:.12em;}
  .tb-head{font-size:.74rem;letter-spacing:.12em;}
  .tb-note{font-size:.74rem;letter-spacing:.1em;}
  .fc-tag{font-size:.74rem;letter-spacing:.14em;}
  .fc-foot .fcf-k{font-size:.74rem;letter-spacing:.14em;}
}

@media (max-width:520px){
  /* Overrides the bundles' own 520px rule, which took the caption
     down to .6rem / 9.6px. */
  .photoslot.has-photo .ph-tag{font-size:.75rem;letter-spacing:.05em;
    left:.6rem;bottom:.6rem;gap:.45rem;}
  .sheet-no{font-size:.72rem;letter-spacing:.12em;gap:.5rem;}
}

/* ============================================================
   3. TAP TARGETS
   ------------------------------------------------------------
   Scoped to pointer:coarse so a mouse keeps the tighter, denser
   layout the design was drawn for. 44px is the Apple/Google
   figure; WCAG 2.2 AA only asks for 24px, which everything here
   already cleared — this is about the thumb, not the audit.

   Links that sit *inside a sentence* are deliberately left alone:
   WCAG exempts them, and padding them out would break the prose.
   ============================================================ */

@media (pointer:coarse){

  /* Footer — the single biggest group: 345 links at 34px. */
  .foot-col a{min-height:44px;display:flex;align-items:center;padding:.35rem 0;}
  .foot-bottom a{display:inline-block;padding:.35rem 0;}

  /* Breadcrumbs were 16px tall. They sit side by side, so growing
     them vertically cannot make two links overlap. */
  .crumb{padding-top:1rem;line-height:1.2;}
  .crumb a{display:inline-block;padding:.6rem .1rem;}
  .crumb .sep{margin:0 .35rem;}

  /* Standalone CTA links ("See how it works →", a studio's phone
     number, "Get directions →"). The hit area is grown with a
     pseudo-element so the ember underline stays on the baseline
     instead of dropping 44px below the words.

     :only-child is what separates a link that stands on its own —
     in a <p>, a .line, a .nap-cta, a .studio-foot — from the ones
     written into a sentence ("...see Remodelers · Homeowners..."),
     which WCAG exempts and which would collide with each other if
     they were padded out. .hero-ctas/.ctarow are the exception:
     the link sits beside a button, so it is not an only child, but
     it is still a standalone call to action. */
  .textlink:only-child,
  .hero-ctas > .textlink,
  .ctarow > .textlink,
  .tb-maps,.fcf-call,.tb-mail{position:relative;}
  .textlink:only-child::after,
  .hero-ctas > .textlink::after,
  .ctarow > .textlink::after,
  .tb-maps::after,.fcf-call::after,.tb-mail::after{
    content:"";position:absolute;left:0;right:0;top:50%;
    transform:translateY(-50%);height:44px;
  }

  /* Stacked at this width, the title block's e-mail and "Addresses
     & maps" sat ~32px apart — close enough that their 44px areas
     overlapped and the lower one swallowed part of the upper. */
  .tb-foot{gap:1.5rem 1.25rem;}

  /* Filter chips (resources) and town chips. */
  .fchip{min-height:44px;padding:.6rem 1.1rem;}
  .towns .chip{min-height:44px;display:inline-flex;align-items:center;}

  /* Forms: a 48px field is the comfortable minimum on a phone, and
     the 1rem font size already there is what keeps iOS from
     zooming the viewport on focus. */
  .field input,.field select{min-height:48px;}
  .studio-pick label{min-height:48px;}
  .form .btn,.ctarow .btn{min-height:48px;}

  /* The booking sheet's studio rows are whole-row links. */
  .tb-row{min-height:56px;align-content:center;}
}

/* ============================================================
   4. :HOVER ON A TOUCH SCREEN
   ------------------------------------------------------------
   Every panel in this design inverts to granite on hover. On a
   phone that fires on tap and *stays* — so after tapping a tile
   the user is left looking at a black card until they tap
   something else. The bundles declare these unconditionally, so
   they are undone here for devices that cannot really hover.
   Base values are restored exactly, including the nth-child tints.
   ============================================================ */

@media (hover:none){
  .tile:hover,.feat:hover,.value:hover,.ptile:hover,
  .pcard:hover,.scard:hover{background:transparent;color:inherit;}
  .pillar:hover{background:var(--bone);color:inherit;}
  .tb-row:hover{background:transparent;color:inherit;
    padding-left:clamp(1rem,2vw,1.3rem);}
  .tb-row:hover::before{transform:scaleY(0);}

  /* The alternating tints the base grids carry. */
  .tile:nth-child(even):hover,
  .ptile:nth-child(even):hover,
  .pcard:nth-child(odd):hover{background:var(--bone-soft);}

  /* Secondary copy inside those panels goes pale on invert. */
  .tile:hover .pline,.ptile:hover .pline{color:var(--slate);}
  .pcard:hover .avoid,.scard:hover .meta{color:var(--slate);}
  .feat:hover p,.value:hover p{color:var(--granite);}
  .pillar:hover p{color:var(--slate);}
  .tb-row:hover .tb-note{color:var(--slate);}
  .tb-row:hover .tb-num{color:var(--ember);}
  .post:hover .ttl{color:inherit;}

  /* The measuring barb that grows on hover, and the blueprint
     corner that flips to its dark variant. */
  .feat:hover .barb,.value:hover .barb{width:26px;}
  .feat:hover::after,.value:hover::after{
    background-image:linear-gradient(var(--grid-ink) 1px,transparent 1px),
                     linear-gradient(90deg,var(--grid-ink) 1px,transparent 1px);
  }

  /* Buttons and inline links: colour-only, but they still strand
     a tapped control in its hover colour. */
  .btn-primary:hover{background:var(--ember);}
  .btn-ghost:hover{background:transparent;color:var(--granite);}
  .dark .btn-ghost:hover{background:transparent;color:var(--bone);}
  .textlink:hover,.navlinks a:hover,.foot-col a:hover,
  .crumb a:hover,.towns a.chip:hover,.tb-mail:hover,
  .tb-maps:hover,.fcf-call:hover{color:inherit;}
  .towns a.chip:hover{border-color:var(--rule);}
  .fchip:hover{border-color:var(--rule);}
  .textlink:hover .arrow{transform:none;}
}

/* ============================================================
   5. NOTCHES, HOME INDICATORS, AND LANDSCAPE
   ============================================================ */

/* The full-width call bar sat directly under the iPhone home
   indicator, which took a bite out of the label. */
@media (max-width:720px){
  .sticky-call .btn{
    padding-bottom:calc(1.05rem + env(safe-area-inset-bottom));
  }
  footer{padding-bottom:calc(8rem + env(safe-area-inset-bottom));}
}

/* A notch sits on the long edge, so it is landscape that needs the
   content column pushed off it. */
@media (orientation:landscape){
  .wrap{
    padding-left:max(var(--pad),env(safe-area-inset-left));
    padding-right:max(var(--pad),env(safe-area-inset-right));
  }
  .mobile-menu a{
    padding-left:max(var(--pad),env(safe-area-inset-left));
    padding-right:max(var(--pad),env(safe-area-inset-right));
  }
}

/* Landscape on a small phone is ~375px tall. A full-width bar plus
   the 70px nav claims a third of it; the floating pill the wider
   breakpoints already use costs almost nothing. */
@media (max-height:480px) and (orientation:landscape){
  .sticky-call{left:auto;right:1rem;bottom:1rem;}
  .sticky-call .btn{
    width:auto;border-radius:var(--radius,2px);
    padding:.7rem 1.1rem;padding-bottom:.7rem;
    box-shadow:0 8px 24px rgba(26,26,26,.22);
  }
  footer{padding-bottom:clamp(3rem,6vw,5rem);}
  section{padding-top:clamp(3rem,7vw,5rem);padding-bottom:clamp(3rem,7vw,5rem);}
}

/* ============================================================
   6. MOTION
   ------------------------------------------------------------
   The hero sweep and the self-drawing blueprints are the site's
   signature and they stay. This only stops the panel from
   animating open on a device where the menu is the navigation.
   ============================================================ */
@media (prefers-reduced-motion:reduce){
  header.nav .mobile-menu{transition:none;}
}

/* ============================================================
   7. THE BOOKING FORM
   ------------------------------------------------------------
   The /book/ form used to be a mockup: a type="button" that
   revealed "this form is not connected yet". It posts for real
   now (inc/leads.php), which adds two states the design never
   had — a validation error and a spam honeypot — plus a focus
   ring, because a real form gets tabbed through.
   ============================================================ */

/* Honeypot. Off-screen rather than display:none: some bots skip
   fields they can tell are hidden, and this one is bait. */
.formcard .hp{
  position:absolute;left:-9999px;top:auto;
  width:1px;height:1px;overflow:hidden;
}

/* Validation message. Ember-ruled like .form-ok, but it has to
   read as a correction rather than a confirmation, so the fill
   carries the tint and the copy sits at body weight. */
.formcard .form-error{
  margin-bottom:.25rem;padding:.85rem 1.05rem;
  border:1px solid var(--ember);border-left-width:3px;
  border-radius:var(--radius);
  background:color-mix(in srgb, var(--ember) 7%, var(--bone));
  color:var(--granite);font-size:.95rem;font-weight:500;
}
.formcard .form-ok:focus-visible,
.formcard .form-error:focus-visible{outline:2px solid var(--granite);outline-offset:3px;}

/* The bundles style :focus but not :focus-visible, so a keyboard
   user got the same near-invisible border change as a mouse
   click. Give the ring real contrast on every control. */
.formcard .field input:focus-visible,
.formcard .field textarea:focus-visible,
.formcard .field select:focus-visible,
.formcard .studio-pick input:focus-visible,
.formcard button:focus-visible{
  outline:2px solid var(--granite);outline-offset:2px;border-color:var(--granite);
}

/* fieldset/legend replaced the div/label around the studio radios
   so the group is announced as one question. Neither element may
   inherit the browser's default box or indent. */
.formcard fieldset{border:0;margin:0;padding:0;min-width:0;}
.formcard legend{padding:0;margin-bottom:.5rem;}

/* ============================================================
   8. FAQ — ANSWERS ON THE PAGE, NOT BEHIND A TAP
   ------------------------------------------------------------
   All 190 Q/A pairs across 38 pages were <details>/<summary>
   accordions: one tap per answer, and the answer text invisible
   until then. They are plain h3 + p now (parts/*, and the
   FAQPage parser in inc/seo.php reads that markup).

   Showing every answer would have tripled the height of these
   sections, so the block is set two-up and one step down the
   type scale: a five-question FAQ now costs roughly what the
   closed accordion did. Hairline rules per item keep the ruled
   rhythm the accordion borders gave the section.

   The .faq details / .faq summary / .pm rules still sitting in
   the 44 page bundles no longer match anything — left alone
   rather than editing 44 near-identical files.
   ============================================================ */

.faq .faqgrid{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:1.4rem 3rem;
}
.faq .qa{
  min-width:0;
  border-top:1px solid var(--rule);
  padding-top:.85rem;
}
/* h3 is clamp(1.2rem,1.7vw,1.5rem) at 700 in every bundle — far
   too loud for a compact block, so the question is pinned to
   body size and the answer sits just under it. */
.faq .qa .q{
  margin:0 0 .3rem;
  font-size:1rem;line-height:1.3;font-weight:700;
  letter-spacing:-0.01em;
}
.faq .qa .ans{
  margin:0;padding:0;
  font-size:.9rem;line-height:1.55;
  color:var(--granite);max-width:54ch;
}
/* .faq h2 was given 2rem of air to clear the first accordion
   border; the items carry their own rule now. */
.faq h2{margin-bottom:1.5rem;}

/* One column below the two-up breakpoint — 880px of .narrow
   split two ways is already tight at tablet width. */
@media (max-width:760px){
  .faq .faqgrid{grid-template-columns:1fr;gap:1.1rem;}
  .faq .qa .ans{max-width:none;}
}

/* -------------------------------------------------------------------------
   Footer column headings.

   These were <h4> under the pages' <h2> section headings, which made every
   one of the 43 pages skip a heading level (h2 -> h4) right at the footer —
   a broken document outline for screen readers and for anything else that
   reads the heading tree. They are top-level site sections, so they are <h2>
   now, and this restores the small-caps look the .foot-col h4 rule in all 44
   page bundles used to give them. Lives here rather than in the bundles for
   the reason in this file's header: it is one edit instead of 44.
   ---------------------------------------------------------------------- */
.foot-col h2{
  font-size:.75rem;text-transform:uppercase;letter-spacing:.18em;
  color:var(--slate);font-weight:600;line-height:1.2;
  margin:0 0 1rem;
}

/* The /book/ form card heading, likewise: it was an <h3> directly under the
   page <h1> with no <h2> between them. Same size, now at the right level. */
.fc-head h2{
  font-size:clamp(1.2rem,1.7vw,1.5rem);font-weight:700;
  letter-spacing:-0.015em;line-height:1.15;
  margin:0 0 .35rem;
}

/* -------------------------------------------------------------------------
   Footer: five columns, not four.

   The "Who walks" list grew from six personas to all twelve on 2026-08-11 —
   six of them were footer-linked from every page and collecting 42 internal
   links each while the other six sat on three to five, and the starved half
   was the commercial cluster. Twelve in one column is a wall, so it runs as
   two, which makes five children under a .foot-top that all 44 page bundles
   declare as `1.4fr 1fr 1fr 1fr`. Without this the fifth column wrapped onto
   its own row underneath.

   The second column's heading is a non-breaking space rather than a repeated
   "Who walks", so the two read as one list; it keeps the columns aligned on
   the same baseline without announcing an empty section heading.

   Here rather than in the bundles for the reason in this file's header: one
   edit instead of 44. The 960px and 720px steps in the bundles still win
   below those widths, which is what we want — five columns collapse to two
   and then to one exactly as four did.
   ---------------------------------------------------------------------- */
@media (min-width:961px){
  .foot-top{grid-template-columns:1.5fr 1fr 1fr 1fr 1fr;gap:1.75rem;}
}

/* -------------------------------------------------------------------------
   Spacing between consecutive body paragraphs.

   All 45 page bundles reset `p{margin:0}` and then space paragraphs by giving
   each section exactly one of them — which held until the four /resources/
   guides and the privacy policy, where a section is several paragraphs of
   running prose. Without this they butt together into one grey block with no
   paragraph breaks at all.

   Scoped to siblings so it cannot add a margin above the first paragraph in a
   section, which is what the section's own padding is for. Same reasoning as
   the footer rule above: one edit here rather than 45 in the bundles.
   ---------------------------------------------------------------------- */
.statement .body + .body,
.wrap .body + .body{ margin-top:1.15rem; }
