/* ============================================================================
   layouts.css — section block variants.

   Colour and type are skin. THIS is what makes two generated sites read as
   different templates rather than the same one repainted: the same content
   rendered in a genuinely different shape.

   Each block below is an alternative rendering of a section the renderer
   already produces. Selected per-site by `layout` (which sets defaults) or
   `sectionVariants` (which overrides individual ones).
   ========================================================================== */

/* ============================================================================
   SERVICES — rows
   Full-bleed alternating image/copy. One item per screen, no card chrome. The
   photograph is the unit rather than a thumbnail inside a box.
   ========================================================================== */
.svc-rows .svc-row{
  display:grid;grid-template-columns:1fr 1fr;align-items:center;
  gap:clamp(24px,5vw,80px);
  max-width:var(--maxw);margin-inline:auto;
  padding-inline:var(--space-gutter);
  padding-block:clamp(32px,5vw,64px);
}
.svc-rows .svc-row.is-flipped .svc-row-media{order:2}
@media (max-width:820px){
  .svc-rows .svc-row{grid-template-columns:1fr;gap:20px}
  .svc-rows .svc-row.is-flipped .svc-row-media{order:0}
}
.svc-row-media{border-radius:var(--radius-lg);overflow:hidden;background:var(--bg-elev-2)}
.svc-row-media img{width:100%;aspect-ratio:4/3;object-fit:cover;display:block;transition:transform .8s var(--ease-out)}
.svc-row:hover .svc-row-media img{transform:scale(1.03)}
.svc-row-num{
  display:block;font-family:var(--font-display);font-size:.82rem;font-weight:600;
  letter-spacing:.2em;color:var(--accent);margin-bottom:14px;
}
.svc-row-body h3{font-size:var(--text-2xl);margin-bottom:14px}
.svc-row-body p{color:var(--fg-muted);font-size:var(--text-lg);max-width:46ch;margin-bottom:16px}
.svc-row-body .price{color:var(--accent);font-family:var(--font-display);font-size:1.2rem;font-weight:600}

/* ============================================================================
   SERVICES — menu
   A priced list. No images: for businesses where the price list is what the
   customer came to read, and a photo per line is noise.
   ========================================================================== */
.svc-menu{max-width:760px}
.svc-menu-row{
  display:grid;grid-template-columns:1fr auto;gap:18px;align-items:baseline;
  padding-block:clamp(16px,2vw,22px);
  border-bottom:1px solid var(--border-soft);
}
.svc-menu-row:first-child{border-top:1px solid var(--border-soft)}
.svc-menu dt{margin:0}
.svc-menu-name{
  display:block;font-family:var(--font-display);
  font-size:var(--text-lg);font-weight:var(--display-weight,600);
  letter-spacing:var(--display-tracking,-0.02em);
}
.svc-menu-desc{display:block;color:var(--fg-muted);font-size:.95rem;margin-top:5px;max-width:56ch}
.svc-menu dd{
  margin:0;font-family:var(--font-display);font-size:1.15rem;font-weight:600;
  color:var(--accent);white-space:nowrap;
}
/* Leader dots between name and price — the detail that makes it read as a
   menu rather than a table. */
.svc-menu-row::after{
  content:"";grid-column:1/-1;order:-1;height:0;
}
@media (max-width:560px){
  .svc-menu-row{grid-template-columns:1fr;gap:6px}
  .svc-menu dd{margin-top:4px}
}

/* ============================================================================
   SERVICES — list
   Editorial. Numbered single column, generous measure, no imagery. Reads as a
   document rather than a catalogue.
   ========================================================================== */
.svc-list{counter-reset:svc;max-width:720px;display:flex;flex-direction:column;gap:clamp(28px,4vw,46px)}
.svc-list li{position:relative;padding-left:clamp(48px,6vw,76px)}
.svc-list li::before{
  counter-increment:svc;content:counter(svc,decimal-leading-zero);
  position:absolute;left:0;top:.1em;
  font-family:var(--font-display);font-size:1.15rem;font-weight:600;
  color:var(--accent);opacity:.6;
}
.svc-list h3{font-size:var(--text-xl);margin-bottom:10px}
.svc-list p{color:var(--fg-muted);font-size:var(--text-lg);line-height:1.7;max-width:60ch}
.svc-list .price{display:inline-block;margin-top:12px;color:var(--accent);font-weight:600}

/* ============================================================================
   SERVICES — compact
   Tight strip for conversion pages. Nothing to scroll past on the way to the
   form.
   ========================================================================== */
.svc-compact{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:clamp(18px,2.4vw,30px)}
.svc-compact-item{padding-left:16px;border-left:2px solid var(--accent)}
.svc-compact-item h3{font-size:1.05rem;margin-bottom:7px}
.svc-compact-item p{color:var(--fg-muted);font-size:.93rem}
.svc-compact-item .price{display:block;margin-top:9px;color:var(--accent);font-weight:600;font-size:.93rem}

/* ============================================================================
   ABOUT — banded
   Full-bleed photograph with copy laid over it. Reads as a moment rather than
   a bio.
   ========================================================================== */
.about-banded{position:relative;overflow:hidden;isolation:isolate;min-height:clamp(420px,60vh,640px);display:flex;align-items:center}
.about-banded-media{position:absolute;inset:0;z-index:0}
.about-banded-media img{width:100%;height:100%;object-fit:cover}
.about-banded-scrim{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    linear-gradient(90deg, color-mix(in srgb,var(--bg) 88%,transparent) 0%,
                    color-mix(in srgb,var(--bg) 55%,transparent) 55%,
                    color-mix(in srgb,var(--bg) 25%,transparent) 100%),
    linear-gradient(180deg, color-mix(in srgb,var(--bg) 40%,transparent) 0%, transparent 40%);
}
.about-banded .wrap{position:relative;z-index:2;width:100%}
.about-banded-body{max-width:52ch}
.about-banded-body h2{font-size:var(--text-2xl);margin-bottom:16px}
.about-banded-body p{color:var(--fg-muted);margin-bottom:14px}
@media (max-width:640px){
  .about-banded-scrim{background:linear-gradient(180deg, color-mix(in srgb,var(--bg) 30%,transparent) 0%, color-mix(in srgb,var(--bg) 92%,transparent) 55%)}
}

/* ============================================================================
   ABOUT — longform
   No image, one narrow column, larger body type. For layouts where the
   argument is the content and a stock team photo would weaken it.
   ========================================================================== */
.about-longform-body{max-width:680px;margin-inline:auto;text-align:center}
.about-longform-body h2{font-size:var(--text-3xl);margin-bottom:24px}
.about-longform-body p{
  color:var(--fg-muted);font-size:clamp(1.05rem, 1rem + .35vw, 1.28rem);
  line-height:1.75;margin-bottom:20px;text-align:left;
}
.about-longform-body .eyebrow{justify-content:center}
.about-longform-body .eyebrow::before{display:none}
.about-longform-body .checklist{max-width:440px;margin-inline:auto;text-align:left}

/* ============================================================================
   HEADER variants
   ========================================================================== */

/* centered — brand above the nav, everything on the middle axis. Editorial. */
header[data-header="centered"] .nav{flex-direction:column;gap:14px;text-align:center}
header[data-header="centered"] .brand{justify-content:center}
header[data-header="centered"] .nav-links{margin-left:0}
header[data-header="centered"] .nav-right{margin-left:0}
@media (max-width:960px){
  header[data-header="centered"] .nav{flex-direction:row}
}

/* minimal — brand and one action only; nav links hidden behind the menu at
   every width. Less chrome competing with a full-bleed hero. */
header[data-header="minimal"] .nav-links{display:none}
header[data-header="minimal"] .hamburger{display:inline-flex}
header[data-header="minimal"] .nav-right{margin-left:auto}

/* bare — no bar at all. The brand floats over the hero with nothing behind it
   and no phone pill; the menu button is the only chrome. For heroes that want
   the top of the page to themselves, which is the single biggest visual
   difference between two builds that otherwise share a design system. */
header[data-header="bare"]{position:absolute;top:0;left:0;right:0;z-index:20;
  background:transparent;border-bottom:0;backdrop-filter:none}
header[data-header="bare"] .nav{padding-block:clamp(18px,2.4vw,30px)}
header[data-header="bare"] .nav-links{display:none}
header[data-header="bare"] .nav-cta{display:none}
header[data-header="bare"] .hamburger{display:inline-flex}
header[data-header="bare"] .nav-right{margin-left:auto}
header[data-header="bare"] + main .hero{padding-top:0}

/* rail — the brand sits alone on the left and the actions hug the far right,
   with the links dropped entirely and a hairline under. Wide and quiet, the
   opposite instinct to a centred stack. */
header[data-header="rail"] .nav{align-items:flex-end;gap:clamp(20px,5vw,80px);
  padding-block:clamp(20px,2.6vw,34px)}
header[data-header="rail"] .brand{flex-direction:column;align-items:flex-start;gap:6px}
header[data-header="rail"] .brand-mark{width:34px;height:34px}
header[data-header="rail"] .nav-links{display:none}
header[data-header="rail"] .hamburger{display:inline-flex}
header[data-header="rail"] .nav-right{margin-left:auto}
header[data-header="rail"]{border-bottom:1px solid var(--border-soft)}

/* ============================================================================
   THE TWO DIALS — density and variance

   A catalog can vary layout, palette and typeface and still read as one
   product, because those never change the page's POSTURE. Measured across the
   36: six of twelve layouts opened with the identical three sections, and all
   36 shared one spacing rhythm and one measure. These two attributes are what
   let a law firm and a detail shop stop sharing DNA.

   Both are set per preset and land on <html>, so they cascade over everything
   without any component needing to know about them.
   ========================================================================== */

/* ---- density: how hard the page breathes ---------------------------------- */

/* Airy — long silences between sections, a narrower measure so the text column
   feels deliberate. For work that wants to look expensive and unhurried. */
[data-density="airy"]{
  --space-section:clamp(120px, 15vw, 240px);
  --space-gutter:clamp(28px, 5vw, 64px);
  --maxw:1180px;
}
[data-density="airy"] .section-head{margin-bottom:clamp(64px, 8vw, 120px);max-width:680px}

/* Dense — sections close together, wider measure, more on screen at once. For
   businesses selling a list: prices, services, availability. */
[data-density="dense"]{
  --space-section:clamp(44px, 5.5vw, 84px);
  --space-gutter:clamp(16px, 3vw, 36px);
  --maxw:1360px;
}
[data-density="dense"] .section-head{margin-bottom:clamp(24px, 3vw, 40px);max-width:820px}
[data-density="dense"] .section-head p{font-size:1rem}

/* ---- variance: how far the grid may break --------------------------------- */

/* Calm — everything on one centred axis, nothing overhangs. Classical, and the
   right answer for trust-led businesses where surprise is a cost. */
[data-variance="calm"] .section-head{margin-inline:auto;text-align:center;max-width:640px}
[data-variance="calm"] .section-head p{margin-inline:auto}
[data-variance="calm"] .hero-inner{text-align:center}
[data-variance="calm"] .hero-ctas,
[data-variance="calm"] .hero-badges{justify-content:center}

/* Bold — the section head is pushed out of the content column and sits against
   the left edge, so the grid visibly breaks at every section boundary. This is
   a structural move, not decoration: it is what stops a page reading as a
   stack of centred blocks. */
[data-variance="bold"] .section > .wrap{max-width:none;padding-inline:clamp(24px,6vw,110px)}
[data-variance="bold"] .section-head{
  max-width:none;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.3fr);
  gap:clamp(20px,4vw,64px);align-items:end;
}
[data-variance="bold"] .section-head p{max-width:52ch;justify-self:start}
[data-variance="bold"] .section-head .eyebrow{grid-column:1;align-self:start}
@media (max-width:820px){
  [data-variance="bold"] .section-head{grid-template-columns:1fr}
}

/* ---- motion: the third dial ----------------------------------------------
   Distance and duration, not on/off. bundle-motion.js still decides WHETHER a
   reveal runs (and reduced-motion still wins over everything); this decides how
   much it moves when it does. A funeral home and a detail shop should not
   arrive on screen the same way.

   Tier 1 never loads the motion bundle at all, so `calm` there is the floor,
   not a style choice. */

/* Calm — a short fade with barely any travel. Dignified, and the right answer
   for care, legal, medical. */
[data-motion="calm"].has-motion .reveal{transform:translateY(8px)}
[data-motion="calm"].has-motion .reveal.in{
  transition:opacity .5s var(--ease-out), transform .5s var(--ease-out);
}

/* Rich — further travel, a touch slower, so entrances read as choreography
   rather than as content settling. For work that is meant to be watched. */
[data-motion="rich"].has-motion .reveal{transform:translateY(40px) scale(.985)}
[data-motion="rich"].has-motion .reveal.in{
  transform:none;
  transition:opacity .95s var(--ease-out), transform .95s var(--ease-out);
}

/* The reduced-motion override in bundle-clean.css already neutralises .reveal;
   these repeat it so a dial can never reintroduce movement someone opted out
   of, whatever the cascade order ends up being. */
@media (prefers-reduced-motion: reduce){
  [data-motion="calm"].has-motion .reveal,
  [data-motion="rich"].has-motion .reveal{opacity:1!important;transform:none!important}
}

/* ---- type: the last shared axis ------------------------------------------
   All 36 templates ran on one type scale, so a bakery and a law firm set their
   headlines identically. Scale alone is not enough — a bigger version of the
   same page is still the same page — so each setting moves size, leading and
   tracking together, which is what actually changes the voice.

   Body stays disciplined in every setting (16-18px, generous leading, capped
   measure). Only the display end moves.
   -------------------------------------------------------------------------- */

/* Compact — the display type steps back and the page reads as information.
   For price lists, schedules, storage, anything where the content is the point
   and the headline is a label. */
[data-type="compact"]{
  --text-hero:clamp(2rem, 0.9rem + 3.4vw, 3.4rem);
  --text-3xl:clamp(1.7rem, 1rem + 2.2vw, 2.7rem);
  --text-2xl:clamp(1.45rem, 1.1rem + 1.3vw, 2.1rem);
  --text-xl:clamp(1.2rem, 1.05rem + .6vw, 1.55rem);
  --text-lg:clamp(1.02rem, .98rem + .2vw, 1.12rem);
}
[data-type="compact"] h1,[data-type="compact"] h2{line-height:1.14;letter-spacing:-.008em}
[data-type="compact"] .hero h1{max-width:26ch}

/* Display — the headline carries the page. Tight leading and real negative
   tracking, which only works at size. For portfolio, hospitality, anything
   sold on feel rather than on specification. */
[data-type="display"]{
  --text-hero:clamp(3.2rem, 0.4rem + 8.4vw, 7.4rem);
  --text-3xl:clamp(2.6rem, 1rem + 4.8vw, 5.4rem);
  --text-2xl:clamp(2rem, 1.2rem + 2.8vw, 3.6rem);
  --text-xl:clamp(1.5rem, 1.1rem + 1.4vw, 2.3rem);
  --text-lg:clamp(1.06rem, 1rem + .3vw, 1.22rem);
}
[data-type="display"] h1,[data-type="display"] h2{line-height:.94;letter-spacing:-.034em}
[data-type="display"] .hero h1{max-width:15ch}
[data-type="display"] .hero .sub{max-width:48ch}
