/* Miska Contracting
   Palette, type and layout are set by the brand book (September 2026).
   Ink, Graphite, Concrete, Mist, Paper. No accent colour, on purpose. */

@font-face{font-family:Bodoni;src:url(../fonts/bodoni-regular.woff2)format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:Bodoni;src:url(../fonts/bodoni-medium.woff2)format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:Jost;src:url(../fonts/jost-light.woff2)format("woff2");font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:Jost;src:url(../fonts/jost-regular.woff2)format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:Jost;src:url(../fonts/jost-medium.woff2)format("woff2");font-weight:500;font-style:normal;font-display:swap}

:root{
  --ink:#121212;
  --graphite:#5a5a58;
  --concrete:#d6d5d1;
  --mist:#edece9;
  --paper:#ffffff;
  --hair:rgba(18,18,18,.15);
  --gutter:clamp(1.25rem,5vw,5rem);
  --measure:74rem;
  --step:clamp(4rem,9vw,8.5rem);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:Jost,"Helvetica Neue",Arial,sans-serif;
  font-weight:300;
  font-size:clamp(1rem,.96rem + .2vw,1.1rem);
  line-height:1.72;
  -webkit-font-smoothing:antialiased;
}
img,svg{max-width:100%;height:auto;display:block}
a{color:inherit}
a.link,.site-foot a.link{
  text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:.24em;
  text-decoration-color:currentColor;
  text-decoration-color:color-mix(in srgb,currentColor 40%,transparent);
  transition:text-decoration-color .3s ease;
}
a.link:hover,a.link:focus-visible{text-decoration-color:currentColor}

/* ---------- type ---------- */
h1,h2,h3,.display{
  font-family:Bodoni,"Times New Roman",serif;
  font-weight:400;           /* never bold */
  line-height:1.08;
  letter-spacing:-.005em;
  margin:0;
  text-wrap:balance;
}
h1{font-size:clamp(2.35rem,1.2rem + 5.2vw,5.1rem)}
h2{font-size:clamp(1.85rem,1.1rem + 2.6vw,3.1rem)}
h3{font-size:clamp(1.3rem,1.05rem + .9vw,1.7rem);line-height:1.2}
p{margin:0 0 1.15em}
p:last-child{margin-bottom:0}
strong{font-weight:500}

.label{
  font-family:Jost,sans-serif;font-weight:500;
  font-size:.66rem;letter-spacing:.34em;text-transform:uppercase;
  color:var(--graphite);margin:0 0 1.6rem;display:block;
}
.lede{font-size:clamp(1.1rem,1rem + .5vw,1.35rem);line-height:1.6;max-width:44ch}
.note{color:var(--graphite);font-size:.92rem;line-height:1.6}
.num{font-family:Jost,sans-serif;font-weight:500;font-variant-numeric:tabular-nums}

/* ---------- shell ---------- */
.wrap{max-width:var(--measure);margin-inline:auto;padding-inline:var(--gutter)}
section{padding-block:var(--step)}
.mist{background:var(--mist)}
.concrete{background:var(--concrete)}
.ink{background:var(--ink);color:var(--paper)}
.ink .label,.ink .note{color:rgba(255,255,255,.62)}
.ink a{color:var(--paper)}
.rule{border:0;border-top:1px solid var(--hair);margin:0}

/* ---------- header ---------- */
.site-head{
  position:sticky;top:0;z-index:40;background:var(--paper);
  border-bottom:1px solid var(--hair);
}
.site-head>.wrap{
  display:flex;align-items:center;justify-content:space-between;
  gap:1.5rem;padding-block:1.1rem;
}
.nav{display:flex;align-items:center;gap:clamp(1.1rem,2.4vw,2.4rem)}
.nav a{
  position:relative;
  font-size:.7rem;letter-spacing:.26em;text-transform:uppercase;
  font-weight:400;text-decoration:none;padding-block:.45rem;
  white-space:nowrap;transition:color .4s ease;
}
/* The underline fades rather than snapping on, which a border cannot do
   convincingly at 1px. */
.nav a::after{
  content:"";position:absolute;left:0;right:0;bottom:.15rem;height:1px;
  background:currentColor;opacity:0;transform:scaleX(.6);transform-origin:left;
  transition:opacity .4s ease,transform .4s cubic-bezier(.22,.61,.36,1);
}
.nav a:hover::after,.nav a:focus-visible::after,
.nav a[aria-current=page]::after{opacity:1;transform:scaleX(1)}
.nav .tel{font-weight:500;letter-spacing:.12em}

/* Over the hero the nav is reversed out. Once the header takes its own ground
   on scroll it goes back to Ink. The Menu button follows at every width,
   because the hero is dark on a phone too, but the links inside the mobile
   dropdown stay Ink since that panel is Paper. */
.site-head .nav-toggle{color:var(--paper);border-color:rgba(255,255,255,.5)}
.site-head[data-solid] .nav-toggle{color:var(--ink);border-color:var(--hair)}
@media (min-width:861px){
  .site-head .nav a{color:var(--paper);text-shadow:0 1px 10px rgba(18,18,18,.55)}
  .site-head[data-solid] .nav a{color:var(--ink);text-shadow:none}
}
.nav-toggle{display:none}

@media (max-width:860px){
  .nav-toggle{
    display:block;background:none;border:1px solid var(--hair);
    font:inherit;font-size:.66rem;letter-spacing:.26em;text-transform:uppercase;
    padding:.6rem 1rem;cursor:pointer;color:var(--ink);
  }
  /* The phone menu itself is further down, under "mobile menu". */
}

/* ---------- hero ---------- */
.hero h1{max-width:22ch;margin-inline:auto;color:var(--paper)}
.hero .actions{justify-content:center;margin-top:.35rem}
.hero .btn,.band .btn{background:var(--paper);color:var(--ink);border-color:var(--paper)}
.hero .btn:hover,.hero .btn:focus-visible,
.band .btn:hover,.band .btn:focus-visible{background:transparent;color:var(--paper)}
.hero .btn.ghost,.band .btn.ghost{background:transparent;color:var(--paper);border-color:rgba(255,255,255,.65)}
.hero .btn.ghost:hover,.hero .btn.ghost:focus-visible,
.band .btn.ghost:hover,.band .btn.ghost:focus-visible{background:var(--paper);color:var(--ink);border-color:var(--paper)}

/* The locality line closes the section, in the same face as the labels above
   it but set back, so it reads as a locator rather than another heading. */
.label.where{margin-top:clamp(2.25rem,4.5vw,3.25rem);color:var(--graphite);opacity:.75}

.opening .label{margin-bottom:1.5rem}
.opening .lede{max-width:52ch}
.opening .actions{margin-top:clamp(2rem,4vw,2.75rem)}

/* ---------- buttons ---------- */
.actions{display:flex;flex-wrap:wrap;gap:.9rem 1.25rem;align-items:center}
.btn{
  display:inline-block;font-family:Jost,sans-serif;font-weight:500;
  font-size:.7rem;letter-spacing:.26em;text-transform:uppercase;
  text-decoration:none;padding:1.05rem 2.1rem;border:1px solid var(--ink);
  background:var(--ink);color:var(--paper);cursor:pointer;
  transition:background .18s ease,color .18s ease;
}
.btn:hover,.btn:focus-visible{background:transparent;color:var(--ink)}
.btn.ghost{background:transparent;color:var(--ink)}
.btn.ghost:hover,.btn.ghost:focus-visible{background:var(--ink);color:var(--paper)}
.ink .btn{border-color:var(--paper);background:var(--paper);color:var(--ink)}
.ink .btn.ghost{background:transparent;color:var(--paper)}
.ink .btn.ghost:hover{background:var(--paper);color:var(--ink)}

/* ---------- grids ---------- */
.split{display:grid;gap:clamp(2.25rem,5vw,4.5rem);grid-template-columns:1fr}
@media(min-width:900px){
  .split{grid-template-columns:minmax(0,13rem) minmax(0,1fr);align-items:start}
  .split.wide{grid-template-columns:minmax(0,20rem) minmax(0,1fr)}
  .split.even{grid-template-columns:1fr 1fr}
}
.cols{display:grid;gap:clamp(2rem,4vw,3.5rem);grid-template-columns:1fr}
@media(min-width:720px){.cols.two{grid-template-columns:1fr 1fr}}
@media(min-width:900px){.cols.three{grid-template-columns:repeat(3,1fr)}}

/* Content blocks. Not a list: no rules, no numbers, no bullets. Headings and
   paragraphs in columns, which is what the content actually is. */
.stack{
  margin:0;padding:0;list-style:none;display:grid;
  gap:clamp(2rem,4vw,3.25rem) clamp(2rem,4vw,3.5rem);
  grid-template-columns:1fr;
}
@media(min-width:760px){.stack{grid-template-columns:repeat(auto-fit,minmax(17rem,1fr))}}
.stack>li{list-style:none}
.stack .row{display:block}
.stack h3{margin-bottom:.75rem}
.stack p{color:var(--graphite);margin:0}

/* proof band */
.proof{display:flex;flex-wrap:wrap;gap:.9rem 2.5rem;align-items:baseline;margin:0;padding:0}
.proof li{list-style:none;font-size:.7rem;letter-spacing:.26em;text-transform:uppercase;font-weight:500}
.proof li span{display:block;font-family:Bodoni,serif;font-weight:400;font-size:1.6rem;letter-spacing:0;text-transform:none;margin-top:.5rem}

/* ---------- form ---------- */
form{max-width:44rem}
.field{margin-bottom:1.9rem}
.field label{
  display:block;font-size:.66rem;letter-spacing:.34em;text-transform:uppercase;
  font-weight:500;color:var(--graphite);margin-bottom:.7rem;
}
.field .hint{font-size:.82rem;color:var(--graphite);letter-spacing:0;text-transform:none;font-weight:300;margin-top:.5rem}
input,select,textarea{
  width:100%;font:inherit;color:var(--ink);background:transparent;
  border:0;border-bottom:1px solid var(--ink);border-radius:0;
  padding:.65rem 0;appearance:none;
}
select{background-image:none}
textarea{min-height:9rem;resize:vertical;line-height:1.6}
input:focus-visible,select:focus-visible,textarea:focus-visible{outline:0;border-bottom-width:2px;margin-bottom:-1px}
input[type=file]{border-bottom:0;padding-left:0;font-size:.9rem}
.hp{position:absolute;left:-9999px}

/* ---------- contact list ---------- */
.direct{margin:0;padding:0}
.direct div{border-bottom:1px solid var(--hair);padding-block:1.4rem}
.direct dt{font-size:.66rem;letter-spacing:.34em;text-transform:uppercase;font-weight:500;color:var(--graphite);margin-bottom:.5rem}
.direct dd{margin:0;font-family:Bodoni,serif;font-size:clamp(1.15rem,1rem + .6vw,1.5rem);line-height:1.25;overflow-wrap:anywhere}
.direct dd a{text-decoration:none;border-bottom:1px solid var(--hair)}
.direct dd a:hover{border-bottom-color:var(--ink)}

/* ---------- footer ---------- */
.site-foot{background:var(--ink);color:var(--paper);padding-block:clamp(3.5rem,7vw,5.5rem);text-align:center}
.site-foot .dog{width:64px;margin:0 auto 2.5rem}
.site-foot a{text-decoration:none}
.site-foot .fnav{display:flex;flex-wrap:wrap;justify-content:center;gap:.6rem 2rem;margin:0 0 2.5rem;padding:0}
.site-foot .fnav li{list-style:none}
.site-foot .fnav a{font-size:.7rem;letter-spacing:.26em;text-transform:uppercase;border-bottom:1px solid transparent}
.site-foot .fnav a:hover{border-bottom-color:rgba(255,255,255,.5)}
.site-foot .meta{display:grid;gap:1.5rem clamp(2rem,5vw,4rem);grid-template-columns:1fr}
@media(min-width:760px){.site-foot .meta{grid-template-columns:repeat(3,1fr)}}
.site-foot .meta p{font-size:.92rem;color:rgba(255,255,255,.72);line-height:1.7}
.site-foot .meta a{border-bottom:1px solid rgba(255,255,255,.3)}
.credit{
  margin-top:clamp(3rem,6vw,4.5rem);padding-top:1.75rem;
  border-top:1px solid rgba(255,255,255,.18);
  display:flex;flex-wrap:wrap;justify-content:center;gap:.75rem 2rem;
  font-size:.62rem;letter-spacing:.26em;text-transform:uppercase;
  color:rgba(255,255,255,.55);
}

.skip{position:absolute;left:-9999px}
.skip:focus{left:var(--gutter);top:.5rem;z-index:99;background:var(--ink);color:var(--paper);padding:.75rem 1.25rem;font-size:.7rem;letter-spacing:.26em;text-transform:uppercase}

@media(prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ==========================================================================
   Photography led layout.
   The references Jake sent (AR Homes, Desert Star) are built the same way:
   a full bleed photograph carrying the page, a very small mark, almost no
   nav, and a serif line sitting low on the image. The brand rules do not
   change: Bodoni never bold, Jost for everything else, no accent colour,
   and the logo reversed out only where a surface is genuinely dark.

   Every image slot reads --photo. Until a photograph is set, the slot falls
   back to a hatch so the layout stays legible.
   ========================================================================== */

:root{
  --hatch:repeating-linear-gradient(135deg,#e8e7e4 0 14px,#dedddA 14px 28px);
  /* One flat translucent black, the same value everywhere. Every full bleed
     photograph on the site wears this and nothing else: no gradients, no per
     image veils, so each picture keeps its own tonal shape and every piece of
     type over one has the same ground under it. */
  --overlay:rgba(18,18,18,.46);
}


/* ---------- header ----------
   Full width, frosted rather than solid so the photograph reads through it,
   and always the black logo: the brand book keeps black on white as the
   default and allows the reversed mark only where a surface is genuinely
   dark. Frosted white is not. On scroll the glass firms up, a hairline
   appears and the full lockup gives way to the dog on its own, which is the
   sanctioned mark below 260px.
   ------------------------------------------------------------------ */
.site-head{
  position:fixed;left:0;right:0;top:0;
  /* Transparent over the hero. The mark stays black, so rather than a white
     bar across the whole width it gets its own Paper ground, bleeding off the
     top and left edges so it reads as a masthead panel and not a sticker.
     The nav beside it is reversed out, because that part is over the photo. */
  background:transparent;
  border-bottom:1px solid transparent;
  transition:background .4s ease,border-color .4s ease,
             -webkit-backdrop-filter .4s ease,backdrop-filter .4s ease;
}

.site-head>.wrap{
  max-width:none;margin-inline:0;
  padding-block:.8rem 1.25rem;
  transition:padding-block .4s ease;
}
.brand{
  position:relative;display:block;line-height:0;
  /* 216px, under the brand book's 260px screen minimum for the full lockup.
     Checked by rendering the mark at both sizes: on a 2x display the browser
     draws the SVG at 432px and it is crisp, and at 1x the fur strokes coarsen
     slightly but hold. Below about 200px they start to fill in, and the book's
     answer there is the dog on its own, which is what the compact and mobile
     states already use. */
  width:216px;height:83px;
  transition:width .4s ease,height .4s ease;
}
.brand img{
  position:absolute;left:0;top:50%;transform:translateY(-50%);
  transition:opacity .35s ease;
}
.brand .full{width:216px}
.brand .mark{width:46px;opacity:0}

.site-head[data-solid]{
  background:rgba(255,255,255,.93);
  -webkit-backdrop-filter:blur(20px) saturate(140%);
  backdrop-filter:blur(20px) saturate(140%);
  border-bottom-color:var(--hair);
}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .site-head[data-solid]{background:rgba(255,255,255,.98)}
}
.site-head[data-solid]>.wrap{padding-block:.7rem}
.site-head[data-solid] .brand{width:46px;height:46px}
.site-head[data-solid] .brand .full{opacity:0}
.site-head[data-solid] .brand .mark{opacity:1}

@media (max-width:860px){
  .brand,.site-head[data-solid] .brand{width:46px;height:46px}
  .brand .full{opacity:0}
  .brand .mark{opacity:1}
}

/* ---------- mobile menu ----------
   A phone gives the whole screen to the menu. One Paper sheet drops from the
   top edge behind the dog and the button, so the header becomes the same
   white bar it turns into on scroll as the sheet passes it, and the sheet
   carries on to the foot of the screen. The pages rise into it one after
   another, set large in Bodoni, and the phone number settles at the bottom in
   the label voice. Closing runs the other way and quicker: the links let go
   and the sheet rolls back up past the header.
   ------------------------------------------------------------------ */
@media (max-width:860px){
  /* The white bar's height: the dog, the bar's padding, the hairline. */
  .site-head{--bar:calc(46px + 1.4rem + 1px)}
  .site-head[data-menu]>.wrap{padding-block:.7rem}

  .nav-toggle{transition:color .25s ease,border-color .25s ease}
  .site-head[data-menu] .nav-toggle{color:var(--ink);border-color:var(--hair)}

  /* Menu and Close share one cell, so the button never changes width. */
  .nav-toggle .lab{display:grid;justify-items:center;overflow:hidden}
  .nav-toggle .lab>span{
    grid-area:1/1;
    transition:transform .45s cubic-bezier(.22,1,.36,1),opacity .3s ease;
  }
  .nav-toggle .lab>span+span{transform:translateY(100%);opacity:0}
  .nav-toggle[aria-expanded=true] .lab>span:first-child{transform:translateY(-100%);opacity:0}
  .nav-toggle[aria-expanded=true] .lab>span+span{transform:none;opacity:1}

  html[data-menu-open]{overflow:hidden}

  .nav{
    /* Behind the dog and the button, in front of everything else. */
    position:absolute;z-index:-1;top:0;left:0;right:0;
    height:100vh;height:100dvh;
    display:flex;flex-direction:column;align-items:stretch;gap:0;
    padding:calc(var(--bar) + clamp(.75rem,3svh,2rem)) var(--gutter)
            max(1.75rem,env(safe-area-inset-bottom));
    background:var(--paper);border:0;
    overflow-y:auto;overscroll-behavior:contain;
    clip-path:inset(0 0 100% 0);
    visibility:hidden;
    transition:clip-path .55s cubic-bezier(.65,0,.35,1),visibility 0s linear .55s;
  }
  .nav[data-open]{
    clip-path:inset(0);
    visibility:visible;
    transition:clip-path .75s cubic-bezier(.22,1,.36,1),visibility 0s;
  }
  /* The header's own hairline sits under the sheet, so the sheet draws it. */
  .nav::before{
    content:"";position:absolute;left:0;right:0;top:calc(var(--bar) - 1px);
    height:1px;background:var(--hair);
  }

  .nav a{
    width:100%;
    font-family:Bodoni,"Times New Roman",serif;font-weight:400;
    font-size:clamp(2rem,9.5vw,2.75rem);line-height:1.1;
    letter-spacing:0;text-transform:none;white-space:normal;
    padding-block:.6rem;
    color:var(--ink);
    opacity:0;transform:translateY(.9rem);
    transition:opacity .2s ease,transform .2s ease,color .4s ease;
  }
  .nav[data-open] a{
    opacity:1;transform:none;
    transition:opacity .6s ease,transform .8s cubic-bezier(.22,1,.36,1),color .4s ease;
    transition-delay:calc(.15s + var(--i,0) * .06s);
  }
  /* The page you are on reads by colour, not by an underline across the
     full width of the sheet. */
  .nav a::after{display:none}
  .nav a[aria-current=page]{color:var(--graphite)}

  .nav .tel{
    margin-top:auto;padding-block:1.75rem .25rem;
    font-family:Jost,sans-serif;font-weight:500;
    font-size:.8rem;line-height:1.4;letter-spacing:.26em;
  }
}

/* No sliding for anyone who has asked their phone for less motion: the sheet
   simply fades, and the links are already in place. */
@media (max-width:860px) and (prefers-reduced-motion:reduce){
  .nav,.nav[data-open]{clip-path:none}
  .nav{opacity:0;transition:opacity .2s ease,visibility 0s linear .2s}
  .nav[data-open]{opacity:1;transition:opacity .2s ease,visibility 0s}
  .nav a,.nav[data-open] a{opacity:1;transform:none;transition:color .4s ease}
  .nav-toggle .lab>span{transition:none}
}

/* ---------- the hero ---------- */
.hero{
  background:var(--ink);
  color:var(--paper);
  min-height:100vh;            /* full screen, the way arhomes.com does it */
  min-height:100svh;           /* and without the mobile url bar cutting it off */
  display:flex;align-items:flex-end;
  text-align:center;
  /* Rule of thirds: the title's own centre sits on the lower third line of
     the frame. Bottom padding is what positions it, and it has to scale with
     the hero rather than sit at a fixed value, so it is worked out from the
     height: a third of the frame, less half the title (88px), less the stack
     under it (198px measured: dots, their margins, and the buttons). The max
     keeps it off the floor on a short window, where the line is unreachable. */
  padding-block:clamp(9rem,14vw,12rem) max(2rem, calc(33.33svh - 198px));
  position:relative;overflow:hidden;
}
.hero::before{                 /* the photograph, on its own layer so it can move */
  content:"";position:absolute;inset:0;
  background:var(--photo,var(--hatch)) center/cover no-repeat;
  transform:scale(1.07);
}
.hero::after{
  content:"";position:absolute;inset:0;background:var(--overlay);
}
.hero>.wrap{position:relative}
.hero>*{position:relative;z-index:1}
/* Same rule on an inner hero, where the title is the only thing in the
   block: a third of 72svh, less half a single line. */
.hero.inner{min-height:min(72svh,42rem);padding-bottom:max(2rem,calc(24svh - 44px))}

/* The home hero cycles three photographs. Each slide is its own layer so one
   can fade up while the last fades out; the section's own ::before stands
   down when slides are present. */
.hero.slideshow::before{display:none}
/* Below the overlay. Without this the slides inherit z-index 1 from
   .hero>* and paint over ::after, and the overlay does nothing. */
.hero .slides{position:absolute;inset:0;overflow:hidden;z-index:0}
.slide{
  position:absolute;inset:0;
  background:var(--photo,var(--hatch)) center/cover no-repeat;
  opacity:0;transition:opacity 1.6s ease-in-out;
}
.slide[data-on]{opacity:1}

/* The dots sit between the rule and the call to action. Small, quiet, and
   large enough to hit: the target is 44px even though the mark is 8px. */
.dots{
  /* These do the dividing now. Each dot is a 44px target around an 8px mark,
     which hides 18px of padding above and below it, so these margins are
     small on purpose: what the eye reads is the margin plus that 18px. */
  display:flex;justify-content:center;gap:.35rem;
  margin-top:.35rem;
}
.dot{
  width:44px;height:44px;padding:0;border:0;background:none;cursor:pointer;
  display:grid;place-items:center;
}
.dot::before{
  content:"";width:8px;height:8px;border-radius:50%;
  border:1px solid rgba(255,255,255,.85);background:transparent;
  transition:background .45s ease,transform .45s ease;
}
.dot[aria-selected="true"]::before{background:var(--paper);transform:scale(1.15)}
.dot:hover::before{background:rgba(255,255,255,.55)}
.dot:focus-visible{outline:2px solid var(--paper);outline-offset:-10px}

/* ---------- full bleed image bands ---------- */
.band{
  background:var(--ink);
  background-image:var(--photo,var(--hatch));
  background-size:cover;background-position:center;
  min-height:min(70svh,40rem);
  display:flex;align-items:flex-end;
  padding:0;position:relative;
}
.band.tall{min-height:min(88svh,52rem)}
.band.short{min-height:min(46svh,24rem)}
.band.quiet{align-items:center;justify-content:center;text-align:center}
.band .caption{
  position:relative;z-index:1;width:100%;
  padding-block:clamp(3rem,6vw,5rem);color:var(--paper);
}
.band.has-text::before{content:"";position:absolute;inset:0;background:var(--overlay)}
.band .caption h2{max-width:20ch}
.band .caption .label{color:rgba(255,255,255,.75)}
.band .caption .lede{color:rgba(255,255,255,.92);margin-top:1.5rem}

/* ---------- half image, half text ---------- */
.duo{display:grid;grid-template-columns:1fr;align-items:stretch;padding-block:0}
.duo .pic{
  background-image:var(--photo,var(--hatch));
  background-size:cover;background-position:center;
  min-height:min(58svh,30rem);
}
.duo .say{padding:var(--step) var(--gutter);display:flex;flex-direction:column;justify-content:center}
.duo .say>div{max-width:34rem;margin-inline:auto;width:100%}
@media(min-width:900px){
  .duo{grid-template-columns:1fr 1fr}
  .duo.flip .pic{order:2}
  .duo .pic{min-height:min(84svh,48rem)}
}

/* a section that sits directly under a fixed header with no hero above it */
.below-head{padding-top:calc(var(--step) + 5rem)}

/* The photography backed elements anchor their copy to the page gutter, in
   line with the logo above it, instead of sitting in the centred reading
   column. On a wide screen a hero headline indented to the column looks
   adrift; under the mark it looks placed. Reading content keeps the column. */
.hero>.wrap,.band .caption>.wrap{width:100%;max-width:none;margin-inline:0}

/* ==========================================================================
   Motion.
   The brand is calm, so everything here is slow, small and one way. A fade
   and an 18px rise, never a slide or a bounce. All of it is off under
   prefers-reduced-motion, and the reveal classes are only applied by
   JavaScript, so with scripting off the page renders fully visible.
   ========================================================================== */

@media (prefers-reduced-motion:no-preference){

  /* the hero photograph settles out of a slight oversize on load */
    /* The settle is for a static hero. A slideshow crossfades instead, and
     re-running a zoom on every change would fight the fade. */
  .hero:not(.slideshow)::before{animation:heroSettle 2.6s cubic-bezier(.16,.84,.44,1) forwards}
  @keyframes heroSettle{to{transform:scale(1)}}

  /* mid page images hold still while the page moves over them.
     Pointer and width guard: iOS ignores fixed attachment with cover and
     renders it badly, so phones get the static version. */
  @media (min-width:900px) and (hover:hover){
    .band{background-attachment:fixed}
    .duo .pic{background-attachment:fixed}
  }

  /* fade and rise as each block enters */
  .reveal-on [data-reveal]{
    opacity:0;transform:translateY(18px);
    transition:opacity .85s cubic-bezier(.22,.61,.36,1),
               transform .85s cubic-bezier(.22,.61,.36,1);
  }
  .reveal-on [data-reveal][data-shown]{opacity:1;transform:none}

}


/* ==========================================================================
   The lock screen. One page, no header, no footer: the mark, a field and a
   button on Paper. Black on white, hairlines, nothing decorative, which is
   what the brand book asks of every document.
   ========================================================================== */
.lock{
  min-height:100svh;display:grid;place-items:center;
  padding:var(--gutter);background:var(--paper);
}
.lock-card{width:100%;max-width:26rem;text-align:center}
.lock-mark{width:260px;margin:0 auto}   /* the stated screen minimum */
.lock .label{margin:clamp(2rem,5vw,2.75rem) 0 0}
.lock-form{
  margin-top:clamp(1.5rem,4vw,2rem);
  display:grid;gap:1.5rem;justify-items:stretch;
}
.lock-form input{
  text-align:center;font-size:1.05rem;letter-spacing:.08em;
  padding:.85rem 0;border-bottom:1px solid var(--ink);
}
.lock-form input::placeholder{color:var(--graphite)}
.lock-form .btn{justify-self:center}
.lock-note{
  margin-top:clamp(2rem,5vw,2.75rem);
  font-size:.8rem;color:var(--graphite);
}
.lock[data-wrong] .lock-form input{border-bottom-color:var(--ink);border-bottom-width:2px}
.lock[data-wrong] .lock-note::before{
  content:"That password did not work. ";color:var(--ink);
}
