@charset "utf-8";
/* ==========================================================================
   The Wabi Sabi Studio — design system
   Structure, type scale, grid and components mirror the reference analysis
   (MANGO-SITE-ANALYSIS.md). Palette remapped to a wabi-sabi warm-earth range.
   To revert to the reference's orange: set --accent:#F77A36 and --ink:#000.
   ========================================================================== */

/* ---------- tokens ----------
   Taken from The Wabi Sabi Studio's own brand style guide
   (site/assets/img/ig-15). Hex values are the studio's labelled codes.   */
:root{
  /* core */
  /* Clay Orange — bright but dulled, sitting 2.58:1 against the page the way
     the reference's #F77A36 sits 2.62:1 against its cream. That low ratio is
     what produces the flat, printed look. Swap via the palette picker. */
  --accent:      #E27940;   /* HSL(21, 74%, 57%)                             */
  --accent-deep: #B85A26;   /* hover / pressed                               */
  --accent-soft: #DF7034;   /* decorative full stop — accent, 3% deeper      */
  --on-accent:   #FFFFFF;   /* bright white on the accent, everywhere        */
  --cream:       #F4EEE2;   /* light tint of Bone — page background          */
  --ink:         #262F21;   /* Dark Olive — text and every border            */

  /* brand palette */
  --bone:    #E5DCC8;       /* Bone / greige — section bands                 */
  --batter:  #E9D2A6;       /* Golden Batter                                 */
  --olive:   #9E9268;       /* Olive Harvest                                 */
  --caramel: #955A2D;       /* Toasted Caramel                               */
  --wine:    #753015;       /* Spiced Wine                                   */
  --cocoa:   #452E16;       /* Cowhide Cocoa                                 */
  --deepwine:#64100A;       /* Deep Wine                                     */
  --slate:   #3F4957;       /* Slate Blue                                    */

  /* aliases kept so existing rules keep working */
  --white:  #FFFFFF;
  --sand:   var(--bone);
  --stone:  #D9CDBE;
  --sage:   var(--olive);
  --clay-d: #452E16;
  --mist:   #EDE6D8;

  --line: 1px solid var(--ink);
  --logo-color: var(--ink);   /* the palette overrides this inline */
  /* The 2.62:1 accent is the poster relationship and is right for fills and
     large display type. At 11px label sizes it is unreadable, so small text
     uses a darkened twin of the same hue that clears WCAG AA 4.5:1. */
  --accent-text: #C94C08;

  /* The reference's block arrow, traced from its own path and pre-rotated.
     preserveAspectRatio="none" reproduces the squash it renders with. */
  --arrow-right: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='20 60 160 80' preserveAspectRatio='none'%3E%3Cpath d='M141.605 140 L178.751 102.999 a4.232 4.232 0 0 0 0 -6.003 L141.605 60 L135.577 66.003 L164.793 95.102 L20 95.102 L20 104.898 L164.791 104.898 L135.579 133.997 Z'/%3E%3C/svg%3E");

  /* The reference's button arrow, its own path, viewBox cropped to the shape's
     bbox so the 30x30 SVG's transparent padding doesn't inflate the gap. */
  --arrow-btn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='49 49.5 100 101'%3E%3Cpath d='m147.839 102.831-46.038 46.498a3.928 3.928 0 0 1-5.6 0 4.027 4.027 0 0 1 0-5.656L135.48 104H52.96c-2.187 0-3.96-1.791-3.96-4s1.773-4 3.96-4h82.519L96.201 56.328a4.027 4.027 0 0 1 0-5.656 3.932 3.932 0 0 1 5.6 0l46.038 46.498c.185.187.351.392.496.613.064.097.108.201.162.302.07.127.146.25.201.386.054.132.085.27.125.405.033.114.077.223.1.341.102.517.102 1.05 0 1.566-.023.118-.067.227-.1.341-.039.136-.071.273-.125.405-.056.135-.132.258-.201.386-.055.101-.098.205-.162.302a3.967 3.967 0 0 1-.496.614z'/%3E%3C/svg%3E");

  --shell: 1180px;
  --gutter: clamp(1.25rem, 4vw, 3.25rem);

  /* Real faces first, free stand-ins behind them. Drop the licensed files in
     (see the @font-face block below) and the site switches over with no other
     change. Previously Playfair was listed first, which would have masked the
     real font even after buying it. */
  --f-display: "Editor's Note", "Editors Note", "Instrument Serif", "Cormorant", Georgia, serif;
  --f-ui: "Clean and Glam Sans", "CleanandGlamSans", "Questrial", "Poppins", "Helvetica Neue", sans-serif;
  /* Questrial has a single weight, so anything that must be bold uses Poppins */
  --f-ui-strong: "Clean and Glam Sans", "Poppins", "Helvetica Neue", sans-serif;
  --f-body: "DM Sans", system-ui, sans-serif;
  /* the reference's three unused faces, now given real jobs.
     Free stand-ins chosen by metric match against the originals. */
  --f-hand:    "Editor's Hand", "Editors Hand", "Shantell Sans", cursive;      /* asides   */
  --f-script:  "Summer Pisces", "Mrs Saint Delafield", cursive;                /* signature*/
  --f-caption: "Montauk", "Montauk Light", "Josefin Sans", sans-serif;         /* captions */
}

/* ==========================================================================
   LICENSED FONTS — the reference site's actual typefaces
   --------------------------------------------------------------------------
   The reference uses two commercial faces. They are NOT bundled here: they are
   paid fonts and copying the files off the reference site's CDN would be a
   licence breach. Buy them, drop the .woff2 files in assets/fonts/, and
   uncomment the two blocks below — the whole site switches over, because these
   names already sit first in --f-display and --f-ui.

     Editor's Note      Jen Wagner Co.  https://jenwagner.co/shop-all-fonts/
                        webfont ~$149 family, single styles from ~$29
                        (not on Adobe Fonts)
     Clean and Glam Sans  Pixel Colours https://www.pixelcolours.com/shop/clean-and-glam-font-duo/
                        ~$26 duo direct, ~$42 webfont on Creative Market

   Until then the site renders in Playfair Display + Jost, which are free and
   close in character. See POSTER-LOOK-RESEARCH.md for the comparison.

@font-face{
  font-family:"Editor's Note";
  src:url("/assets/fonts/editors-note-extralight.woff2") format("woff2");
  font-weight:200 300; font-style:normal; font-display:swap;
}
@font-face{
  font-family:"Editor's Note";
  src:url("/assets/fonts/editors-note-extralight-italic.woff2") format("woff2");
  font-weight:200 300; font-style:italic; font-display:swap;
}
@font-face{
  font-family:"Clean and Glam Sans";
  src:url("/assets/fonts/clean-and-glam-sans.woff2") format("woff2");
  font-weight:400 700; font-style:normal; font-display:swap;
}
   ========================================================================== */

/* ---------- reset ---------- */
*,*::before,*::after{box-sizing:border-box}
/* full-bleed bands use 100vw, which counts the scrollbar — without clipping on
   the root the extra px propagate and the whole page scrolls sideways */
html{-webkit-text-size-adjust:100%;overflow-x:clip}
body{
  margin:0;
  background:var(--cream);
  color:var(--ink);
  font-family:var(--f-body);
  font-size:1rem;
  line-height:1.7;
  letter-spacing:.05em;
  overflow-x:clip;
}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
h1,h2,h3,h4,h5,h6{margin:0;font-weight:400}
p{margin:0 0 1.1em}
ul{margin:0;padding:0;list-style:none}

:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* ---------- matte poster finish ----------
   A fixed grain plate over the whole page gives the printed / risograph
   tooth the brand's own graphics have. Sits above everything, catches
   no pointer events. */
body::after{
  content:"";position:fixed;inset:0;z-index:9999;pointer-events:none;
  opacity:.5;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23g)' opacity='.5'/%3E%3C/svg%3E");
  background-size:300px 300px;
}
/* warm paper wash — knocks the digital edge off the photography */
.media img,.hero__media img{filter:saturate(.9) contrast(1.03) brightness(1.01)}
@media (prefers-reduced-motion: no-preference){
  .media img{transition:filter .4s}
}
.post:hover .media img,.collage .media:hover img{filter:saturate(1) contrast(1.03)}

/* ---------- layout ---------- */
.shell{width:min(100% - var(--gutter)*2, var(--shell));margin-inline:auto}
.bleed{width:100vw;margin-inline:calc(50% - 50vw)}
/* the reference runs ~800px sections; our old 7.5rem block padding was adding
   ~240px per section and inflating the whole page rhythm */
.section{padding-block:clamp(3rem, 5.5vw, 5rem)}
.section--tight{padding-block:clamp(2rem, 3.5vw, 3rem)}

/* ---------- type scale (reference ratios, fluid) ---------- */
.d1,.d2,.d2b,.d3,.d4,.d5,.d6{font-family:var(--f-display);font-weight:300;letter-spacing:-.005em}
.d1{font-size:clamp(2.9rem, 8.4vw, 6.9375rem); line-height:1.0}   /* 111px */
.d2{font-size:clamp(2.4rem, 6.2vw, 4.8125rem); line-height:1.0}   /*  77px */
.d2b{font-size:clamp(2.15rem, 5.4vw, 4.4375rem);line-height:1.0}  /*  71px */
.d3{font-size:clamp(2.05rem, 5vw, 4.125rem);   line-height:1.0}   /*  66px */
.d4{font-size:clamp(1.8rem, 4vw, 3.5rem);      line-height:1.1}   /*  56px */
.d5{font-size:clamp(1.6rem, 3vw, 2.75rem);     line-height:1.0}   /*  44px */
.d6{font-size:clamp(1.35rem, 2.1vw, 2.1875rem);line-height:1.35}  /*  35px */

/* the signature move: italic word, swapped glyph, coloured full stop */
.d1 em,.d2 em,.d2b em,.d3 em,.d4 em,.d5 em{font-style:italic}
.dot{color:var(--accent-soft);font-weight:700}

.lede{font-size:clamp(1rem,1.5vw,1.125rem);letter-spacing:.056em;max-width:46ch}
.body-lg{font-size:1.0625rem}

/* UI type — tiny, bold, wide */
.ui,.ui-xs,.ui-sm,.ui-md,.ui-lg{
  font-family:var(--f-ui);font-weight:400;text-transform:uppercase;
}
.ui-xs{font-size:.5625rem;letter-spacing:.16em;line-height:1.3}  /*  9px */
.ui-sm{font-size:.6875rem;letter-spacing:.15em;line-height:1.3}  /* 11px */
.ui   {font-size:.75rem;  letter-spacing:.14em;line-height:1.3}  /* 12px */
.ui-md{font-size:.8125rem;letter-spacing:.13em;line-height:1.3}  /* 13px */
.ui-lg{font-size:1rem;    letter-spacing:.12em;line-height:1.3}  /* 16px */

.eyebrow{font-family:var(--f-ui-strong);font-weight:600;font-size:.6875rem;
  letter-spacing:.22em;text-transform:uppercase;color:var(--accent-text);margin-bottom:1.25rem}

/* ---------- buttons (10px radius, 1px ink border — from the reference) ---------- */
/* Reference sets button labels at 700. Gap is .7rem because its own text-to-
   arrow distance measures ~11.5px once the SVG's padding is accounted for. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.7rem;
  border-radius:10px;border:var(--line);
  padding:.9rem 1.6rem;min-height:44px;
  font-family:var(--f-ui);font-weight:700;font-size:.75rem;
  letter-spacing:.14em;text-transform:uppercase;
  transition:background-color .2s, color .2s, transform .2s;
  text-align:center;
}
/* Arrow colour is the opposite of the fill: orange on a light button, ink on
   an accent one — the reference's rule, and it survives a palette change. */
.btn::after{
  content:"";flex:0 0 auto;width:15px;height:15px;
  background-color:var(--btn-arrow, var(--accent));
  -webkit-mask:var(--arrow-btn) no-repeat center/100% 100%;
          mask:var(--arrow-btn) no-repeat center/100% 100%}
.btn--primary{--btn-arrow:var(--ink);background:var(--accent);color:var(--on-accent)}
.btn--primary:hover{background:var(--accent-deep);color:#FFFFFF}
.btn--secondary{background:var(--white);color:var(--ink)}
.btn--secondary:hover{background:var(--ink);color:var(--cream)}
.btn--ghost{background:transparent;color:var(--ink)}
.btn--ghost:hover{background:var(--ink);color:var(--cream)}
.btn--wide{width:100%}
.btn:active{transform:translateY(1px)}

.btn-row{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:2rem}
.btn-stack{display:grid;gap:.75rem;margin-top:2rem;max-width:440px}

/* ---------- announcement bar ---------- */
/* reference geometry: 40px announcement bar, 106px masthead, 101x102 menu tile */
/* the reference closes the orange strip with the same hairline it rules
   everything else with (it measures 0.667px there) */
.announce{background:var(--accent);color:var(--on-accent);height:40px;
  border-bottom:var(--line);display:flex;align-items:center}
/* Three tracks, not flex: the reference centres its message on the PAGE, and a
   flex row lets the social block shove it left by half the icons' width. */
.announce .shell{display:grid;grid-template-columns:1fr auto 1fr;
  align-items:center;gap:1rem;width:min(100% - 2rem, 1400px)}
.announce__msg{grid-column:2;text-align:center;font-weight:700}
.announce .social{grid-column:3;justify-self:end}
.announce__msg a{display:inline-flex;align-items:center;gap:.5rem}
.announce__msg a:hover{text-decoration:underline;text-underline-offset:3px}
.social{display:flex;align-items:center;gap:.65rem}
.social a{width:44px;height:44px;margin:-10px;display:grid;place-items:center;
  border-radius:50%;transition:transform .2s,opacity .2s;opacity:.92}
.social a:hover{transform:translateY(-2px);opacity:1}
.social svg{width:16px;height:16px;fill:currentColor}

/* ---------- header ---------- */
.masthead{border-bottom:var(--line);background:var(--cream)}
/* Reference splits the FULL page width into three equal columns and centres one
   thing in each — tag, logo, tag. A max-width shell can't reproduce that. */
.masthead .shell{width:100%;max-width:none}
.masthead__inner{display:grid;grid-template-columns:repeat(3,1fr);
  align-items:center;justify-items:center;gap:0;height:105px;padding-block:0}
/* Reference: 202px wide, 700, and justified — which is why its middle line has
   the stretched word spacing. Justify only works on lines the browser breaks
   itself, so the copy wraps naturally here instead of using <br>. */
/* Client: larger, and the words should not sit so far apart. `justify` was the
   cause — it stretches the word gaps to force both edges flush. Dropped it,
   pulled the tracking back from .15em, and widened the block so the bigger
   type still breaks over three lines. */
.masthead__tag{width:250px;font-weight:700;font-size:.8125rem;
  letter-spacing:.06em;line-height:1.5;text-align:left}
.masthead__tag--right{text-align:right}
/* Below ~1220px a centred first-column tag would slide under the 101px MENU
   tile, so pin both tags to their edges until there is room again. */
@media (max-width:1220px){
  .masthead__tag{justify-self:start;margin-left:117px}
  .masthead__tag--right{justify-self:end;margin-left:0;margin-right:var(--gutter)}
}
.wordmark{font-family:var(--f-display);font-weight:400;font-size:clamp(1.6rem,3.4vw,2.5rem);
  line-height:1;letter-spacing:.02em;text-align:center;white-space:nowrap}
.wordmark .dot{color:var(--accent)}
.wordmark small{display:block;font-family:var(--f-ui);font-weight:700;
  font-size:.5rem;letter-spacing:.4em;margin-top:.45rem;color:var(--accent)}

/* fixed MENU tile — reference: 101×102 solid accent, top-left.
   Its label sits ABOVE the bars (label at 19,17; bars 51x32 at 25,47 with three
   2.7px rules 12px apart), which is the opposite of how we had it stacked. */
.menu-tile{
  --bar-pitch:14.7px;
  position:fixed;top:0;left:0;z-index:60;
  width:101px;height:102px;background:var(--accent);color:var(--on-accent);
  border:var(--line);   /* box-sizing keeps the tile 101x102 */
  /* flex, not block: a <button> with a fixed height centres its anonymous
     content box, which was pushing the whole stack 12px down. */
  display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start;
  text-align:left;padding:17px 0 0 19px;
  transition:background-color .2s;
}
.menu-tile:hover{background:var(--accent-deep)}
.menu-tile .ui-lg{display:block;font-weight:700;line-height:20.8px}
.menu-tile__bars{display:grid;gap:12px;width:51px;margin:9px 0 0 6px}
.menu-tile__bars span{display:block;width:51px;height:2.7px;background:currentColor;
  transition:transform .25s, opacity .2s}
.menu-tile[aria-expanded="true"] .menu-tile__bars span:nth-child(1){transform:translateY(var(--bar-pitch)) rotate(45deg)}
.menu-tile[aria-expanded="true"] .menu-tile__bars span:nth-child(2){opacity:0}
.menu-tile[aria-expanded="true"] .menu-tile__bars span:nth-child(3){transform:translateY(calc(var(--bar-pitch) * -1)) rotate(-45deg)}

/* ---------- mega menu (full-screen lightbox, cream) ---------- */
.mega{position:fixed;inset:0;z-index:55;background:var(--cream);
  overflow-y:auto;padding:7rem var(--gutter) 4rem;
  opacity:0;visibility:hidden;transition:opacity .28s ease, visibility .28s}
.mega[data-open="true"]{opacity:1;visibility:visible}
.mega__grid{display:grid;gap:2.5rem 2rem;
  grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  width:min(100% - 0px, var(--shell));margin-inline:auto}
.mega__col h2{font-family:var(--f-ui);font-weight:400;font-size:.6875rem;
  letter-spacing:.22em;text-transform:uppercase;color:var(--accent);
  padding-bottom:.85rem;margin-bottom:1.1rem;border-bottom:var(--line)}
.mega__col li+li{margin-top:.2rem}
.mega__col a{font-family:var(--f-display);font-weight:300;
  font-size:clamp(1.25rem,2vw,2rem);line-height:1.35;display:inline-block;
  transition:color .2s, transform .2s}
.mega__col a:hover{color:var(--accent);transform:translateX(6px)}
.mega__foot{width:min(100%, var(--shell));margin:3.5rem auto 0;
  padding-top:2rem;border-top:var(--line);
  display:flex;flex-wrap:wrap;gap:1.5rem;align-items:center;justify-content:space-between}
.mega__foot .social a{width:34px;height:34px;border:var(--line);border-radius:50%}
.mega__foot .social svg{width:15px;height:15px}
body[data-menu="open"]{overflow:hidden}

/* ---------- hero ---------- */
/* Reference geometry at 1707px: section 711 tall, image 845 wide x 709 (one
   half, bled to the edge), text column exactly 490 wide, buttons 232x45.
   The reference hero carries a headline and two buttons only — no paragraph. */
/* ---------- panel rules ----------
   The reference draws a 1px black hairline at nearly every section boundary —
   16 of them on its homepage. That ruling is what makes the page read as a set
   of printed panels rather than a continuous scroll. One rule per boundary:
   every band takes a top rule, none take a bottom, so lines never double up. */
main > section, main > div{border-top:var(--line)}
main > :first-child{border-top:0}
.hero{border-bottom:0}
.hero__grid{display:grid;grid-template-columns:1fr 1fr;align-items:stretch;
  min-height:711px}
.hero__copy{display:flex;flex-direction:column;justify-content:center;
  padding-block:clamp(2rem,4vw,3rem)}
/* The reference column is 490px because its hero carries no body copy. Ours does,
   so the column is widened into the empty space beside it and the display size
   steps down — the band stays 711px, the text shrinks to fit rather than the
   section growing. */
.hero__copy > *{max-width:620px}
/* Instrument Serif is narrower than the old fallback, so the headline can run
   larger and still break on 4 lines like the reference's does */
.hero .d1{font-size:clamp(2.5rem, 5.5vw, 5.75rem)}   /* 92px cap in the hero */
.hero .lede{font-size:clamp(.9375rem, 1.15vw, 1.0625rem);max-width:560px}
.hero__media{position:relative;min-height:340px;overflow:hidden}
/* the hero image must never drive the row height — tall portrait crops would
   otherwise stretch the band well past the reference's 711px */
.hero__media .ph,.hero__media .media{position:absolute;inset:0;height:100%;aspect-ratio:auto}
/* whole frame at its own ratio, scaled until top and bottom meet the band.
   Specificity has to beat both `.media img` and `.media--fill img`, which are
   declared later in this file. */
.media.media--whole{display:flex;align-items:stretch;justify-content:center;
  background:transparent}
.media.media--whole img{position:static;inset:auto;
  height:100%;width:auto;max-width:none;object-fit:contain}
/* hero buttons are fixed, equal blocks — not content-width */
.hero .btn{width:232px;height:45px;min-height:0;padding-block:0}

@media (min-width:901px){
  /* bleed the image half out to the viewport edge */
  .hero__media{margin-right:calc(-1 * max(var(--gutter), (100vw - var(--shell)) / 2))}
  /* nudge the copy toward the centre of its half, as the reference does */
  .hero__copy{padding-right:var(--gutter)}
}

/* ---------- real photography ----------
   .media wraps an <img> and keeps the same box behaviour the placeholders had */
/* Every photograph is framed the way a button is — 1px ink, 10px radius. That
   is what the reference does too: its contained images sit in a wrapper at
   `1px solid rgb(0,0,0)` / `10px`, matching its buttons exactly.
   The radius comes off where a frame meets the viewport edge, since a rounded
   corner there would curve away from nothing. The border still runs. */
.media,.igstrip__grid a{position:relative;overflow:hidden;
  border:var(--line);border-radius:10px}
.media{background:var(--bone)}
.bleed > .media,
.hero__media .media,
.hero__media .ph{border-radius:0}
.media img{width:100%;height:100%;object-fit:cover;display:block}
.media--fill img,.media img{min-height:100%}
.media--ratio-1{aspect-ratio:1}
.media--ratio-45{aspect-ratio:4/5}
.media--ratio-34{aspect-ratio:3/4}
.media--ratio-169{aspect-ratio:16/9}
.media--ratio-21{aspect-ratio:2/1}
/* full-bleed photo bands are a fixed band height in the reference (674px),
   not an aspect ratio — otherwise they grow unboundedly on wide screens */
.bleed > .media{aspect-ratio:auto;height:clamp(320px, 53vw, 674px)}
/* Whole frame, original ratio, scaled until its top and bottom meet the band —
   height drives the fit, width follows. No crop, no letterboxing top or bottom. */
.media--band{aspect-ratio:auto;background:transparent;
  display:flex;align-items:stretch;justify-content:center}
.media--band img{height:100%;width:auto;max-width:none;object-fit:contain}

/* Section whose paired image runs flush to the band's top and bottom edges.
   The section drops its own vertical padding and the text column carries it
   instead, so the picture spans the full height with no gap above or below. */
.section--flushmedia{padding-block:0}
.section--flushmedia .split{align-items:stretch}
.section--flushmedia .split > :not(.split__media){
  padding-block:clamp(3rem, 5.5vw, 5rem);align-self:center}
/* the text column sets the row height; the image is taken out of flow so its
   intrinsic 1280px cannot stretch the band, then scaled to fill what remains */
/* holds the band at the height it had before the image was made flush
   (576px @1280, 741px @1707) so the picture scales UP to fill it,
   rather than the section shrinking down to meet the picture */
.section--flushmedia .split__media{position:relative;
  min-height:clamp(430px, 45vw, 741px)}
.section--flushmedia .media--band{position:absolute;inset:0;height:auto}

/* the logo lockup shown as page content (contact page) — never cropped */
.media--logo{aspect-ratio:1;background:transparent}
.media--logo img{object-fit:contain;mix-blend-mode:multiply}
.media--fill{position:absolute;inset:0}
.media--fill img{position:absolute;inset:0}
/* focal-point nudges for tall crops */
.media--top img{object-position:50% 22%}
.media--face img{object-position:50% 30%}
.media--low img{object-position:50% 72%}
/* anchor to the bottom edge: whatever has to go is taken off the top */
.media--bottom img{object-position:50% 100%}

/* logo lockup — the supplied artwork is black on white, so multiply drops
   the white out against any warm background */
.logo{display:block;mix-blend-mode:multiply;width:auto}
/* reference logo is 252x87 inside a 106px bar. Ours is a square emblem, so it
   can match the height but not the width — see README for the lockup note.
   95px in the unchanged 105px row, on the trimmed mark: the ink itself now
   stands 95px instead of the 59px it managed inside the padded square. */
.logo--head{height:95px}
/* 70px because the footer's old square file rendered its ink at 104 x 0.675;
   the trimmed mark at 70px is the same size on the page as before. */
.logo--foot{height:70px}
.logo--menu{height:88px}

/* The stock photos were all chosen orange, at the reference's own hue. Rotating
   that hue is what re-tints them to whichever theme is active — --img-hue is
   set by the palette. Only object/still-life shots carry this class; the ones
   with people are left alone because a hue rotation wrecks skin tones. */
/* These have to restate the paper wash from `.media img` rather than just add
   hue-rotate: `filter` is one property, so a second declaration replaces the
   chain instead of extending it, and .media img outranks a bare class. */
img.stockimg--tint,
.media img.stockimg--tint,
.hero__media img.stockimg--tint{
  filter:hue-rotate(var(--img-hue,0deg)) saturate(.9) contrast(1.03) brightness(1.01)}
.post:hover .media img.stockimg--tint,
.collage .media:hover img.stockimg--tint{
  filter:hue-rotate(var(--img-hue,0deg)) saturate(1) contrast(1.03)}
/* No transition here. `.media img` animates filter for the hover wash, but
   interpolating a 165deg rotation sweeps the photo through every hue on the
   way — a hard cut is both faster and better looking. */
img.stockimg--tint,.media img.stockimg--tint{transition:none}

/* ---------- the two logos ---------- */
/* Emblem: the trimmed mark is black-on-transparent, so its alpha makes a clean
   mask and the colour underneath is what you actually see. That is what lets
   the emblem take a theme colour at all — an <img> could not. */
.logo--emblem{display:block;aspect-ratio:669/741;background-color:var(--logo-color);
  -webkit-mask:url("/assets/img/logo-mark.png") no-repeat center/contain;
          mask:url("/assets/img/logo-mark.png") no-repeat center/contain}
.logo--type{display:block;width:auto;fill:var(--logo-color)}
/* Instrument Serif ships one weight (400), so font-weight:700 would only get
   the browser's synthetic bold — inconsistent between engines. Stroking the
   glyphs and painting the stroke behind the fill emboldens them evenly and by
   a controllable amount. Widening is pure tracking, so the cap height, and
   with it the lockup's vertical size, does not move. */
.logo--type .lw__lg{font-family:var(--f-display);font-weight:300;font-style:italic;
  font-size:58px;letter-spacing:.075em;text-anchor:middle;
  stroke:var(--logo-color);stroke-width:1.05;stroke-linejoin:round;paint-order:stroke fill}
.logo--type .lw__sm{font-family:var(--f-ui-strong);font-weight:700;
  font-size:12px;letter-spacing:.65em;text-anchor:middle;
  stroke:var(--logo-color);stroke-width:.35;stroke-linejoin:round;paint-order:stroke fill}
/* one variant at a time; emblem is the default when no attribute is set yet */
:root .logo--type{display:none}   /* wordmark retired — emblem is the locked mark */

/* ---------- placeholder media (swap for real photography) ---------- */
.ph{position:relative;overflow:hidden;background:
  linear-gradient(135deg, var(--sand) 0%, var(--stone) 55%, var(--mist) 100%);}
.ph::before{content:"";position:absolute;inset:0;opacity:.5;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.32'/%3E%3C/svg%3E");}
.ph::after{content:attr(data-label);position:absolute;left:1rem;right:1rem;bottom:1rem;
  font-family:var(--f-ui);font-weight:700;font-size:.5625rem;letter-spacing:.2em;
  text-transform:uppercase;color:var(--clay-d);opacity:.6;text-align:center}
.ph--clay{background:linear-gradient(150deg,#DCC3B2 0%, #C69C82 60%, #E8DACB 100%)}
.ph--sage{background:linear-gradient(150deg,#CBD3C3 0%, #9DAA94 60%, #E4E7DC 100%)}
.ph--stone{background:linear-gradient(150deg,#E3DACD 0%, #C3B6A5 60%, #F1EAE0 100%)}
.ph--deep{background:linear-gradient(150deg,#B08268 0%, #7D4230 70%, #C79A7F 100%)}
.ph--deep::after{color:#FBF4EC;opacity:.75}
.ph--ratio-1{aspect-ratio:1}
.ph--ratio-45{aspect-ratio:4/5}
.ph--ratio-34{aspect-ratio:3/4}
.ph--ratio-169{aspect-ratio:16/9}
.ph--ratio-21{aspect-ratio:2/1}

/* ---------- marquee ---------- */
/* The reference SECTION is 131px, but 28px of that is dead cream outside the
   rules (12px above, 16px below). The strip you actually see — rule to rule —
   is 103px. Ours is a solid fill, so 103px is the number that matches. */
.marquee{border-top:var(--line);background:var(--cream);
  min-height:103px;display:flex;align-items:center;
  overflow:hidden;white-space:nowrap}
.marquee--display{min-height:127px}
.marquee--accent{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.marquee__track{display:inline-flex;gap:0;animation:slide 38s linear infinite;will-change:transform}
.marquee:hover .marquee__track,.marquee:focus-within .marquee__track{animation-play-state:paused}
.marquee__track span{padding-inline:1.1rem}
/* Reference runs a flat 40px on Editor's Note ExtraLight Italic. Instrument
   Serif sets 13.1% narrower at the same size (BRANDING DESIGN: 264.5px vs
   299.2px), so 45.2px is what makes the two strips read at the same size.
   Band stays 131px, so the text now fills more of it — as in the reference. */
.marquee:not(.marquee--display) .marquee__track{
  font-family:var(--f-display);font-weight:300;
  font-size:clamp(1.75rem, 4.4vw, 2.825rem);font-style:italic;line-height:1.2;
  letter-spacing:.02em}
.marquee--display .marquee__track span{font-family:var(--f-display);font-weight:300;
  font-size:clamp(2rem,4.4vw,3.3125rem);text-transform:none;letter-spacing:0}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* ---------- service cards (2-col grid, reference §7 §6) ---------- */
.grid-2{display:grid;grid-template-columns:1fr;
  gap:clamp(2rem,4vw,3.75rem) clamp(2rem,5vw,5.5rem)}
@media (min-width:768px){.grid-2{grid-template-columns:repeat(2,minmax(0,1fr))}}
.grid-3{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:2rem}
.grid-4{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:2rem}

/* Reference puts the rule UNDER each block, not over it: copy → 11px → rule,
   then 42px of air before the next block's title. */
.svc{border-bottom:var(--line);padding-bottom:11px}
/* Reference hangs a 33x21 arrow off the right edge of each block, centred on
   the title. Its own SVG is an up-arrow rotated 90deg into a squashed box;
   the path below is that shape already rotated, so no transform is needed.
   Drawn as a mask so the fill tracks --accent when the palette changes. */
.svc h3{display:flex;align-items:center;justify-content:space-between;
  gap:1.5rem;margin-bottom:.7rem}
.svc h3::after{
  content:"";flex:0 0 auto;width:33px;height:21px;background-color:var(--accent);
  -webkit-mask:var(--arrow-right) no-repeat center/100% 100%;
          mask:var(--arrow-right) no-repeat center/100% 100%}
.svc p{margin:0;font-size:1rem;letter-spacing:.05em}
/* Montauk Light's job: captions and meta lines — light, geometric, wide */
/* `.svc p{margin:0}` is more specific than `.svc__meta`, so the selector has to
   name the element to win the margin back */
.svc p.svc__meta{margin-top:.7rem;color:var(--accent-text);
  font-family:var(--f-ui-strong);font-weight:600;letter-spacing:.14em}
.caption{font-family:var(--f-caption);font-weight:300;font-size:.9375rem;
  letter-spacing:.06em;opacity:.8}

/* Editor's Hand's job: asides — attributions, notes, anything in a side voice */
.aside-note{font-family:var(--f-hand);font-size:1rem;letter-spacing:.01em;
  text-transform:none;opacity:.85}

/* Summer Pisces' job: a signature, nothing else */
.signature{font-family:var(--f-script);font-size:clamp(2.4rem,4.5vw,3.6rem);
  line-height:1.1;color:var(--accent);letter-spacing:.02em;display:block}

/* ---------- split band ---------- */
.split{display:grid;grid-template-columns:1fr 1fr;align-items:center;
  gap:clamp(2rem,5vw,5rem)}
.split--reverse .split__media{order:-1}
@media (max-width:820px){.split{grid-template-columns:1fr}.split--reverse .split__media{order:0}}

/* ---------- half/half two-up (Education/Events pattern) ---------- */
.duo{display:grid;grid-template-columns:1fr 1fr;gap:0;border-top:var(--line)}
.duo__cell{padding:clamp(2rem,4vw,3.5rem) clamp(1.5rem,3vw,3rem)}
.duo__cell+.duo__cell{border-left:var(--line)}
@media (max-width:820px){
  .duo{grid-template-columns:1fr}
  .duo__cell+.duo__cell{border-left:0;border-top:var(--line)}
}

/* ---------- collage ----------
   Explicit row heights: the tiles hold real 9:16 photography, so without a
   fixed track the tall tile stretches its row and leaves a void beside it. */
.collage{display:grid;gap:1rem;grid-template-columns:repeat(4,1fr);
  grid-template-rows:repeat(2, clamp(170px, 25vw, 330px))}
.collage>*{min-height:0;min-width:0}
.collage .ph,.collage .media{border-radius:10px;height:100%;aspect-ratio:auto}
.collage__a{grid-column:span 2;grid-row:span 2}
.collage__b{grid-column:span 1}
.collage__c{grid-column:span 1}
.collage__d{grid-column:span 2}
@media (max-width:760px){
  .collage{grid-template-columns:repeat(2,1fr);
    grid-template-rows:repeat(3, clamp(130px, 30vw, 190px))}
  .collage__a{grid-column:span 2;grid-row:span 1}
  .collage__d{grid-column:span 2}
}

/* ---------- reviews ---------- */
.reviews{position:relative}
.review{display:none}
.review[data-active="true"]{display:block;animation:fade .45s ease}
@keyframes fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
.review__quote{font-family:var(--f-display);font-weight:300;
  font-size:clamp(1.5rem,3.1vw,2.8125rem);line-height:1.0;margin-bottom:1.75rem}
.review__by{color:var(--accent-text)}
.reviews__nav{display:flex;gap:.6rem;margin-top:2rem;align-items:center}
.reviews__nav button{width:42px;height:42px;border:var(--line);border-radius:50%;
  display:grid;place-items:center;transition:background-color .2s,color .2s}
.reviews__nav button:hover{background:var(--ink);color:var(--cream)}
.reviews__count{margin-left:.6rem;color:var(--accent-text)}

/* ---------- blog cards ---------- */
.post{display:block;transition:transform .25s}
.post:hover{transform:translateY(-4px)}
.post .ph{margin-bottom:1.1rem}
.post h3{margin-bottom:.55rem}
.post__cat{color:var(--accent-text);margin-bottom:.6rem;display:block}
.post p{font-size:1rem;margin:0}

/* ---------- process steps ---------- */
.step{border-top:var(--line);padding-top:1.25rem}
.step__num{font-family:var(--f-display);font-size:2.75rem;line-height:1;
  color:var(--accent);display:block;margin-bottom:.6rem}

/* ---------- pricing / package cards ---------- */
.pkg{border:var(--line);border-radius:12px;padding:clamp(1.5rem,2.5vw,2.25rem);
  background:var(--white);display:flex;flex-direction:column}
.pkg--feature{background:var(--ink);color:var(--cream);border-color:var(--ink)}
.pkg--feature .pkg__price,.pkg--feature .pkg__label{color:var(--sand)}
/* This one is a secondary button repainted accent, so it needs the accent
   button's ink arrow — orange on orange would vanish. */
.pkg--feature .btn--secondary{--btn-arrow:var(--ink);
  background:var(--accent);color:var(--white);border-color:var(--accent)}
.pkg--feature li::before{background:var(--sand)}
.pkg__label{color:var(--accent-text);margin-bottom:.9rem}
.pkg__price{font-family:var(--f-display);font-size:clamp(2rem,3.6vw,2.9rem);
  line-height:1;margin:.4rem 0 1.4rem;color:var(--accent)}
/* The slot was sized for a numeral. Words need to come down a lot or they run
   to three lines and shove the feature list off the card. */
.pkg__price--quote{font-size:clamp(1.15rem,1.6vw,1.4rem);line-height:1.25;
  font-style:italic;letter-spacing:.01em}
.pkg ul{margin:0 0 1.75rem;display:grid;gap:.6rem;flex:1}
.pkg li{position:relative;padding-left:1.4rem;font-size:1rem;letter-spacing:.05em}
.pkg li::before{content:"";position:absolute;left:0;top:.62em;width:7px;height:7px;
  border-radius:50%;background:var(--accent)}

/* ---------- FAQ accordion ---------- */
.faq{border-top:var(--line)}
.faq__item{border-bottom:var(--line)}
.faq__q{width:100%;display:flex;justify-content:space-between;align-items:center;
  gap:1.5rem;padding:1.35rem 0;text-align:left;font-family:var(--f-display);
  font-weight:300;font-size:clamp(1.35rem,2.1vw,2.1875rem);line-height:1.35}
.faq__q:hover{color:var(--accent)}
.faq__icon{flex:none;width:24px;height:24px;position:relative}
.faq__icon::before,.faq__icon::after{content:"";position:absolute;left:50%;top:50%;
  background:currentColor;transition:transform .25s}
.faq__icon::before{width:14px;height:1.5px;transform:translate(-50%,-50%)}
.faq__icon::after{width:1.5px;height:14px;transform:translate(-50%,-50%)}
.faq__item[data-open="true"] .faq__icon::after{transform:translate(-50%,-50%) scaleY(0)}
.faq__a{display:grid;grid-template-rows:0fr;transition:grid-template-rows .3s ease}
.faq__item[data-open="true"] .faq__a{grid-template-rows:1fr}
.faq__a>div{overflow:hidden}
.faq__a p{padding-bottom:1.4rem;margin:0;max-width:68ch}

/* ---------- founders (about page only) ----------
   One shared portrait in the middle, a card either side, hand-drawn arrows
   pointing from each card to the right person. */
.founders{position:relative;display:grid;align-items:center;
  grid-template-columns:1fr minmax(280px,420px) 1fr;
  gap:clamp(1.5rem,3vw,3rem)}
.founders__photo{margin:0;grid-column:2;position:relative;z-index:1}
.founders__photo img{width:100%;height:auto;border-radius:2px}
.founders__card{position:relative;z-index:2}
.founders__card--left{grid-column:1;grid-row:1;text-align:right}
.founders__card--right{grid-column:3;grid-row:1}
.founders__role{color:var(--accent-text);margin:.75rem 0 1.25rem}

.founders__arrows{position:absolute;inset:0;width:100%;height:100%;
  pointer-events:none;z-index:3;overflow:visible}
.founders__arrow,.founders__head{
  stroke:var(--accent);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;fill:none;
  vector-effect:non-scaling-stroke}
/* pale casing keeps the arrow readable where it crosses dark clothing */
.founders__casing path{
  stroke:var(--cream);stroke-width:7;stroke-linecap:round;stroke-linejoin:round;fill:none;
  vector-effect:non-scaling-stroke;opacity:.92}

@media (max-width:900px){
  .founders{grid-template-columns:1fr;gap:2rem}
  .founders__photo{grid-column:1;grid-row:1;max-width:420px;margin-inline:auto}
  .founders__card--left,.founders__card--right{grid-column:1;text-align:left}
  .founders__card--left{grid-row:2}
  .founders__card--right{grid-row:3}
  .founders__arrows{display:none}
}

/* ---------- values list ---------- */
.values li{position:relative;padding-left:2rem;margin-bottom:1rem;
  font-size:1.0625rem;letter-spacing:.045em}
.values li::before{content:"";position:absolute;left:0;top:.72em;
  width:11px;height:11px;border-radius:50%;border:var(--line);background:var(--accent)}

/* ---------- newsletter ---------- */
.subscribe__form{display:flex;flex-wrap:wrap;gap:.75rem;margin-top:1.75rem;max-width:520px}
.field{flex:1 1 240px}
input[type=text],input[type=email],input[type=tel],select,textarea{
  width:100%;background:var(--white);border:var(--line);border-radius:10px;
  padding:.85rem 1rem;font-family:var(--f-body);font-size:.9375rem;
  letter-spacing:.04em;color:var(--ink);min-height:46px}
textarea{min-height:130px;resize:vertical}
label{display:block;margin-bottom:.45rem}
.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:1.1rem}
.form-grid .full{grid-column:1/-1}
@media (max-width:640px){.form-grid{grid-template-columns:1fr}}
.form-note{margin-top:1rem;color:var(--accent-text)}
.form-status{margin-top:1rem;padding:.9rem 1.1rem;border:var(--line);border-radius:10px;
  background:var(--white);display:none}
.form-status[data-show="true"]{display:block}

/* ---------- footer ---------- */
.footer{border-top:var(--line);padding-block:clamp(2.5rem,5vw,4rem) 2rem;background:var(--cream)}
.footer__grid{display:grid;gap:2.5rem;
  grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}
.footer h2{font-family:var(--f-ui);font-weight:400;font-size:.6875rem;
  letter-spacing:.22em;text-transform:uppercase;color:var(--accent-text);margin-bottom:1.1rem}
.footer nav li{line-height:2.4}
.footer nav a:hover{color:var(--accent)}
.footer__brand .wordmark{text-align:left}
.footer__legal{margin-top:3rem;padding-top:1.4rem;border-top:var(--line);
  display:flex;flex-wrap:wrap;gap:.5rem 1.2rem;align-items:center;justify-content:space-between}
.footer__legal a:hover{color:var(--accent)}

/* ---------- palette picker (development aid) ----------
   Delete this block and the buildPicker() call in main.js to ship without it. */
.palette{position:fixed;right:1rem;bottom:1rem;z-index:10000;
  font-family:var(--f-ui);text-align:right}
.palette__toggle{background:var(--ink);color:var(--cream);
  border-radius:100px;padding:.6rem 1rem;letter-spacing:.16em}
.palette__panel{display:none;margin-top:.6rem;background:var(--cream);
  border:var(--line);border-radius:12px;padding:1rem;text-align:left;
  box-shadow:0 12px 32px rgba(38,47,33,.16);max-width:260px}
.palette[data-open="true"] .palette__panel{display:block}
.palette__title{color:var(--accent-text);margin:0 0 .75rem}
.palette__meta + .palette__title{margin-top:1.25rem}
.palette__logos + .palette__title{margin-top:.25rem}
.palette__list{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:.85rem}
.palette__swatch{width:34px;height:34px;border-radius:8px;border:var(--line);
  transition:transform .15s}
.palette__swatch:hover{transform:translateY(-2px)}
.palette__logos,.palette__imgs{display:flex;gap:.5rem;margin-bottom:.85rem}
.palette__opt{border:var(--line);border-radius:8px;padding:.45rem .8rem;
  background:var(--white);color:var(--ink);letter-spacing:.14em;
  text-transform:uppercase;transition:background-color .2s,color .2s}
.palette__opt:hover{background:var(--ink);color:var(--cream)}
.palette__opt[data-active="true"]{background:var(--accent);color:var(--on-accent);
  border-color:var(--accent)}
.palette__swatch[data-active="true"]{outline:2px solid var(--ink);outline-offset:2px}
.palette__meta{margin:0;line-height:1.8;letter-spacing:.08em;text-transform:none}
.palette__note{opacity:.65;font-style:italic}
@media print{.palette{display:none}}

/* ---------- misc ---------- */
.page-head{padding-block:clamp(2.5rem,6vw,5rem)}   /* next band supplies the rule */
.rule{height:1px;background:var(--ink);opacity:.18;margin-block:clamp(2rem,4vw,3.5rem)}
/* keep a heading on one line, shrinking with the viewport instead of wrapping */
.nowrap{white-space:nowrap;font-size:min(clamp(2.4rem,6.2vw,4.8125rem), 11vw)}
@media (max-width:520px){.nowrap{font-size:9.2vw}}

.center{text-align:center}
.mx-auto{margin-inline:auto}
.muted{opacity:.72}
.tag{display:inline-block;border:var(--line);border-radius:100px;padding:.35rem .85rem;
  margin:0 .4rem .5rem 0}
.skip{position:absolute;left:-9999px}
.skip:focus{left:1rem;top:1rem;z-index:99;background:var(--ink);color:var(--cream);
  padding:.75rem 1.25rem;border-radius:8px}

/* reveal on scroll — visible by default so content survives a JS failure;
   only hidden once main.js has confirmed it will observe (html.js) */
.reveal{opacity:1;transform:none}
html.js .reveal{opacity:0;transform:translateY(22px);
  transition:opacity .7s cubic-bezier(.2,.7,.3,1), transform .7s cubic-bezier(.2,.7,.3,1)}
html.js .reveal[data-seen="true"]{opacity:1;transform:none}

/* ---------- responsive ---------- */
@media (max-width:900px){
  .masthead__inner{grid-template-columns:1fr;justify-items:center;text-align:center;gap:.9rem}
  .masthead__tag{display:none}
  .hero__grid{grid-template-columns:1fr}
  .hero__copy{padding:clamp(2rem,7vw,3rem) 0}
  .hero__media{min-height:56vw}
  .menu-tile{--bar-pitch:9px;width:64px;height:64px;padding:10px 0 0 11px}
  .menu-tile .ui-lg{font-size:.5rem;letter-spacing:.1em;line-height:13px}
  .menu-tile__bars{width:34px;gap:7px;margin:6px 0 0 4px}
  .menu-tile__bars span{width:34px;height:2px}
}
@media (max-width:560px){
  .announce .shell{flex-direction:column;gap:.5rem;padding-block:.6rem}
  .announce__msg{text-align:center}
  .btn-row .btn{width:100%}
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important}
  .reveal,html.js .reveal{opacity:1;transform:none}
}

@media print{.menu-tile,.mega,.announce{display:none}}

/* ---------- audit fixes ---------- */
/* §6/§7: the blog grid is the one grid that breaks the shell to the edges */
.grid-4--bleed{width:100vw;margin-inline:calc(50% - 50vw);
  padding-inline:var(--gutter);
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr))}
@media (min-width:1200px){.grid-4--bleed{grid-template-columns:repeat(4,minmax(0,1fr))}}

/* paired CTAs are fixed 232px blocks throughout, not just in the hero */
@media (min-width:600px){
  .btn-row .btn{min-width:232px}
}

/* full-bleed brand band — the logo as a palate cleanser between sections */
/* band height is fixed to what it was; the logo now takes far more of it,
   so the padding shrinks instead of the section growing */
.brandband{background:var(--bone);border-top:var(--line);
  display:grid;place-items:center;
  height:clamp(261px, 34vw, 505px);padding-block:0}
/* ~88% of the band at every width — percentage height can't be used here
   because the centred grid item has no definite height to resolve against */
.brandband__logo{width:auto;height:clamp(230px, 30vw, 444px);
  max-width:88vw;object-fit:contain;mix-blend-mode:multiply}

/* portfolio tiles are links, not inert boxes */
.tile{display:block;position:relative;cursor:pointer}
.tile::after{content:"";position:absolute;inset:0;background:var(--ink);
  opacity:0;transition:opacity .25s}
.tile:hover::after,.tile:focus-visible::after{opacity:.12}

/* §5.5 Instagram strip — the reference carries one above the footer on inner pages */
.igstrip{border-top:var(--line);background:var(--cream)}
.igstrip__head{display:flex;flex-wrap:wrap;gap:.75rem;align-items:baseline;
  justify-content:space-between;padding-block:1.25rem}
.igstrip__grid{display:grid;grid-template-columns:repeat(6,1fr);gap:2px;
  width:100vw;margin-inline:calc(50% - 50vw)}
.igstrip__grid a{position:relative;aspect-ratio:1;overflow:hidden;display:block}
.igstrip__grid img{width:100%;height:100%;object-fit:cover}
.igstrip__grid a::after{content:"";position:absolute;inset:0;background:var(--accent);
  opacity:0;transition:opacity .25s;mix-blend-mode:multiply}
.igstrip__grid a:hover::after{opacity:.35}
@media (max-width:760px){.igstrip__grid{grid-template-columns:repeat(3,1fr)}}



/* ── Package cards ────────────────────────────────────────────────────
   Four columns against 8-12 feature bullets produced very tall, very narrow
   boxes. Two columns doubles the card width, and setting the feature list in
   two internal columns halves what is left — roughly a quarter of the height
   at the same content. Nothing removed. */
.pkg-grid{display:grid;grid-template-columns:1fr;
  gap:clamp(1.5rem,3vw,2.25rem)}
@media (min-width:900px){ .pkg-grid{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:900px){
  .pkg-grid .pkg ul{column-count:2;column-gap:2rem}
  .pkg-grid .pkg li{break-inside:avoid;-webkit-column-break-inside:avoid}
}
/* the price and CTA span the full card so the two columns read as one block */
.pkg-grid .pkg{gap:0}
.pkg-grid .pkg .btn{margin-top:auto}

/* ══════ EDITORIAL DEVICES ═══════════════════════════════════════════════
   Everything below is scoped to :root[data-enhanced="on"] so the Changes
   panel can turn the whole set off and show the page as it was. Nothing here
   adds or removes content — it is all typographic treatment. */

/* ── 1. Drop cap ──────────────────────────────────────────────────────
   The box height is set from JS to an exact multiple of the paragraph's
   line-height, measured per font. Guessing at an em size is what made the
   lines wrap unevenly: a floated initial only sits clean when its box is a
   whole number of lines tall. */
:root[data-enhanced="on"] .lede--open::first-letter{
  float:left;font-family:var(--f-display);font-weight:300;
  font-size:var(--dc-size, 3.5em);
  line-height:var(--dc-lh, .78);
  margin:var(--dc-mt, .04em) .10em 0 0;
  color:var(--accent-text)}

/* ── 2. Pull quote ────────────────────────────────────────────────────
   Brighter and bigger than the first pass: full accent, no fade. It should
   read as a piece of the layout, not a watermark. */
:root[data-enhanced="on"] .review{position:relative}
:root[data-enhanced="on"] .review__quote{position:relative}
:root[data-enhanced="on"] .review__quote::before{
  content:"“";position:absolute;left:-.60em;top:-.30em;
  font-family:var(--f-display);font-size:4.6em;line-height:1;
  color:var(--accent);opacity:.9;pointer-events:none}
@media (max-width:760px){
  :root[data-enhanced="on"] .review__quote::before{left:-.14em;font-size:3.4em;opacity:.75}
}
:root[data-enhanced="on"] .review__by{display:flex;align-items:center;gap:.85rem;margin-top:1.6rem}
:root[data-enhanced="on"] .review__by::before{
  content:"";width:34px;height:2px;background:var(--accent);flex:none}

/* ── 3. Figure caption ────────────────────────────────────────────────
   Editorial layouts credit their imagery. `.caption`'s voice, finally used
   under a photograph. */
.figure{margin:0}
:root[data-enhanced="on"] .figure figcaption{
  font-family:var(--f-caption);font-weight:300;font-size:.8125rem;
  letter-spacing:.06em;line-height:1.5;opacity:.72;
  margin-top:.7rem;padding-left:1rem;border-left:var(--line)}
:root[data-enhanced="on"] .figure.bleed figcaption{margin-top:1rem;padding-bottom:.25rem}
:root:not([data-enhanced="on"]) .figure figcaption{display:none}

/* ── 4. Rule above section headers ────────────────────────────────────
   A hairline the full width of the column, the way a print section opens.
   Uses the same 1px ink as every other rule on the page. */
:root[data-enhanced="on"] .sec-rule{
  border-top:var(--line);padding-top:1.4rem}

/* ── 5. Card lift ─────────────────────────────────────────────────────
   The package cards were inert. A small rise and a deeper rule on hover
   makes the grid feel handled rather than printed-and-frozen. */
:root[data-enhanced="on"] .pkg{
  transition:transform .25s ease, box-shadow .25s ease}
@media (hover:hover){
  :root[data-enhanced="on"] .pkg:hover{
    transform:translateY(-6px);
    box-shadow:0 18px 40px -28px rgba(0,0,0,.55)}
}
@media (prefers-reduced-motion:reduce){
  :root[data-enhanced="on"] .pkg{transition:none}
  :root[data-enhanced="on"] .pkg:hover{transform:none;box-shadow:none}
}

/* ══════ CHANGES PANEL ═══════════════════════════════════════════════ */
.changes{position:fixed;right:1.25rem;bottom:4.6rem;z-index:70;
  font-family:var(--f-ui);text-align:right}
.changes__toggle{background:var(--accent);color:var(--on-accent);
  border:var(--line);border-radius:999px;padding:.55rem 1.1rem;
  letter-spacing:.16em;text-transform:uppercase;font-weight:700;cursor:pointer}
.changes__panel{display:none;margin-top:.6rem;background:var(--cream);
  border:var(--line);border-radius:12px;padding:1rem;width:290px;
  text-align:left;box-shadow:0 24px 60px -30px rgba(0,0,0,.6);
  max-height:70vh;overflow:auto}
.changes[data-open="true"] .changes__panel{display:block}
.changes__head{display:flex;align-items:center;justify-content:space-between;
  gap:.6rem;margin-bottom:.9rem}
.changes__title{color:var(--accent-text);margin:0;letter-spacing:.2em;
  text-transform:uppercase;font-weight:700}
.changes__ab{border:var(--line);border-radius:999px;padding:.3rem .7rem;
  background:var(--white);color:var(--ink);cursor:pointer;
  letter-spacing:.12em;text-transform:uppercase;font-weight:700;white-space:nowrap}
.changes__ab[data-state="off"]{background:var(--ink);color:var(--cream)}
.changes__item{display:flex;align-items:flex-start;justify-content:space-between;
  gap:.6rem;padding:.55rem 0;border-top:var(--line)}
.changes__item:first-of-type{border-top:0}
.changes__name{line-height:1.45}
.changes__what{display:block;opacity:.62;margin-top:.15rem}
.changes__go{border:var(--line);border-radius:999px;background:var(--white);
  color:var(--ink);padding:.25rem .6rem;cursor:pointer;flex:none;
  letter-spacing:.1em;text-transform:uppercase;font-weight:700}
.changes__go:hover{background:var(--accent);color:var(--on-accent);border-color:var(--accent)}
.changes__hint{margin:.9rem 0 0;opacity:.6;line-height:1.6}
.changes__skin{width:100%;border:var(--line);border-radius:999px;
  background:var(--white);color:var(--ink);padding:.45rem .8rem;margin-bottom:.9rem;
  cursor:pointer;letter-spacing:.12em;text-transform:uppercase;font-weight:700}
.changes__skin[data-state="on"]{background:var(--accent);color:var(--on-accent);
  border-color:var(--accent);box-shadow:3px 3px 0 var(--ink)}
/* the target flashes so the eye lands on it */
@keyframes changeflash{0%,100%{box-shadow:0 0 0 0 rgba(247,122,54,0)}
  18%{box-shadow:0 0 0 10px rgba(247,122,54,.35)}}
.change-flash{animation:changeflash 1.5s ease}
@media (prefers-reduced-motion:reduce){.change-flash{animation:none;outline:2px solid var(--accent);outline-offset:6px}}
@media (max-width:560px){.changes{right:.75rem;bottom:4.2rem}.changes__panel{width:min(84vw,290px)}}

/* ══════ POSTER SKIN ═════════════════════════════════════════════════════
   What this look is actually called, having gone and checked:

     · RISOGRAPH  — the print process. Few spot inks, no blending, visible
       paper grain, and plates that never register perfectly, so colours sit a
       hair off each other. That misregistration is the signature.
     · HALFTONE / BEN-DAY DOTS — how comics and newsprint fake a tone with
       one solid ink. It is the dot screen you see in a manga page.
     · NEO-BRUTALIST POSTER — the layout half. Thick ink keylines, hard
       offset shadows with no blur, zero radius, blocks tilted a degree.
     · COMIC PANEL GRID — heavy gutters, panels of unequal size.

   All of it is one skin, off by default, switched from the Changes panel.
   Same palette. No content added or removed — every rule here is surface. */

:root[data-skin="poster"]{
  --ink-w: 2.5px;              /* keyline weight */
  --hard: 6px 6px 0 var(--ink);/* offset block, never blurred */
  --dot: 3.4px;                /* halftone pitch */
}

/* paper: grain over the cream so it reads as stock, not screen */
:root[data-skin="poster"] body::before{
  content:"";position:fixed;inset:0;z-index:1;pointer-events:none;
  opacity:.5;mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='.30'/%3E%3C/svg%3E")}

/* halftone: a dot screen laid over the whole page in the brand ink */
:root[data-skin="poster"] body::after{
  content:"";position:fixed;inset:0;z-index:1;pointer-events:none;
  opacity:.14;mix-blend-mode:multiply;
  background-image:radial-gradient(var(--ink) 32%, transparent 33%);
  background-size:var(--dot) var(--dot)}

/* keylines and hard shadows — the neo-brutalist half */
:root[data-skin="poster"] .media,
:root[data-skin="poster"] .igstrip__grid a,
:root[data-skin="poster"] .pkg,
:root[data-skin="poster"] .btn,
:root[data-skin="poster"] .menu-tile,
:root[data-skin="poster"] .duo__cell{
  border:var(--ink-w) solid var(--ink);border-radius:0}
:root[data-skin="poster"] .pkg,
:root[data-skin="poster"] .btn{box-shadow:var(--hard)}
/* the block shadow is part of the print, not something that animates in —
   only the lift itself should transition */
:root[data-skin="poster"] .pkg{transition-property:transform}
:root[data-skin="poster"] .media{box-shadow:var(--hard)}

/* mechanical press: the block moves onto its own shadow */
:root[data-skin="poster"] .btn{transition:transform .06s linear, box-shadow .06s linear}
:root[data-skin="poster"] .btn:active{transform:translate(6px,6px);box-shadow:0 0 0 var(--ink)}

/* panels sit a degree off true, the way a pasted-up page does */
:root[data-skin="poster"] .pkg:nth-child(odd){transform:rotate(-.5deg)}
:root[data-skin="poster"] .pkg:nth-child(even){transform:rotate(.45deg)}
:root[data-skin="poster"] .pkg:hover{transform:rotate(0deg) translateY(-6px)}

/* comic gutters: panels want air between them, not a hairline */
:root[data-skin="poster"] .collage{gap:1.5rem}
:root[data-skin="poster"] .igstrip__grid{gap:8px}

/* halftone the photographs themselves — one dot screen per panel, so images
   read as printed plates rather than photos dropped on paper */
:root[data-skin="poster"] .media{position:relative}
:root[data-skin="poster"] .media::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:2;
  mix-blend-mode:multiply;opacity:.26;
  background-image:radial-gradient(var(--ink) 34%, transparent 35%);
  background-size:4.6px 4.6px}
/* and push the ink: fewer tones, more contrast, the way one plate prints */
:root[data-skin="poster"] .media img{filter:contrast(1.16) saturate(1.12)}

/* misregistration — the riso signature. A second impression of the headline
   sits a hair off in the accent, as though the plate shifted. */
:root[data-skin="poster"] .d1,
:root[data-skin="poster"] .d2,
:root[data-skin="poster"] .d3{
  text-shadow:2.5px 2.5px 0 var(--accent)}
@media (prefers-reduced-motion:reduce){
  :root[data-skin="poster"] .pkg{transform:none}
}

/* the eyebrow becomes a stamped tag */
:root[data-skin="poster"] .eyebrow{
  display:inline-block;background:var(--accent);color:var(--on-accent);
  padding:.35rem .7rem;border:var(--ink-w) solid var(--ink);
  box-shadow:3px 3px 0 var(--ink)}

/* marquee band gets its keyline top and bottom, like a printed rule */
:root[data-skin="poster"] .marquee{
  border-top:var(--ink-w) solid var(--ink);
  border-bottom:var(--ink-w) solid var(--ink)}

/* section hairlines thicken to printed rules */
:root[data-skin="poster"] .sec-rule{border-top:var(--ink-w) solid var(--ink)}
:root[data-skin="poster"] .svc{border-bottom:var(--ink-w) solid var(--ink)}

/* keep the drop cap and pull quote, but let them print heavier */
:root[data-skin="poster"] .lede--open::first-letter{color:var(--accent);
  text-shadow:2px 2px 0 var(--ink)}
:root[data-skin="poster"] .review__quote::before{opacity:1}

/* mobile: dial the texture back so small type stays clean */
@media (max-width:560px){
  :root[data-skin="poster"]{--ink-w:2px;--hard:4px 4px 0 var(--ink)}
  :root[data-skin="poster"] body::after{opacity:.10}
  :root[data-skin="poster"] .media::after{opacity:.18}
  :root[data-skin="poster"] .d1,:root[data-skin="poster"] .d2,
  :root[data-skin="poster"] .d3{text-shadow:1.5px 1.5px 0 var(--accent)}
}

/* ── Poster skin, applied across the whole page ───────────────────────
   Same three moves everywhere, not just on buttons and cards: a hard offset
   block with no blur, zero radius, and a half-degree of tilt on things that
   read as pasted-on panels.

   Two rules about where it can and cannot go:
   · Full-bleed elements (announce bar, marquee, footer, bleed bands) get the
     keyline but NOT the shadow — a shadow on something that runs off the
     viewport just gets clipped and looks like a mistake.
   · Nothing that holds running text gets tilted. Panels tilt; paragraphs do
     not, because rotated body copy is unpleasant to read. */

/* everything square */
:root[data-skin="poster"] .tag,
:root[data-skin="poster"] .reviews__nav button,
:root[data-skin="poster"] .field input,
:root[data-skin="poster"] .field select,
:root[data-skin="poster"] .field textarea,
:root[data-skin="poster"] input[type=text],
:root[data-skin="poster"] input[type=email],
:root[data-skin="poster"] input[type=tel],
:root[data-skin="poster"] select,
:root[data-skin="poster"] textarea,
:root[data-skin="poster"] .changes__panel,
:root[data-skin="poster"] .changes__toggle,
:root[data-skin="poster"] .changes__go,
:root[data-skin="poster"] .changes__ab,
:root[data-skin="poster"] .changes__skin,
:root[data-skin="poster"] .palette__panel,
:root[data-skin="poster"] .palette__toggle,
:root[data-skin="poster"] .palette__opt{border-radius:0}

/* ── header ── keyline only: it spans the viewport */
:root[data-skin="poster"] .announce{border-bottom:var(--ink-w) solid var(--ink)}
:root[data-skin="poster"] .masthead{border-bottom:var(--ink-w) solid var(--ink)}

/* ── MENU tile ── a stuck-on block, so it gets the full treatment */
:root[data-skin="poster"] .menu-tile{
  box-shadow:var(--hard);transform:rotate(-1deg);transform-origin:top left}
:root[data-skin="poster"] .menu-tile:active{transform:rotate(-1deg) translate(6px,6px);box-shadow:none}

/* ── sections ── a printed rule opening each one */
:root[data-skin="poster"] .section,
:root[data-skin="poster"] .section--tight{border-top:var(--ink-w) solid var(--ink)}
:root[data-skin="poster"] .hero{border-top:0}

/* ── footer ── keyline, and its legal strip too */
:root[data-skin="poster"] .footer{border-top:var(--ink-w) solid var(--ink)}
:root[data-skin="poster"] .footer__legal{border-top:var(--ink-w) solid var(--ink)}

/* ── service rows, FAQ, tags ── */
:root[data-skin="poster"] .faq{border-top:var(--ink-w) solid var(--ink)}
:root[data-skin="poster"] .faq__item{border-bottom:var(--ink-w) solid var(--ink)}
:root[data-skin="poster"] .tag{
  border:var(--ink-w) solid var(--ink);box-shadow:3px 3px 0 var(--ink)}
:root[data-skin="poster"] .tag:hover{transform:translate(3px,3px);box-shadow:none}

/* ── media panels ── tilt alternately so the grid reads as pasted-up */
:root[data-skin="poster"] .collage .media:nth-child(odd),
:root[data-skin="poster"] .grid-3 .media:nth-child(odd),
:root[data-skin="poster"] .grid-4 .media:nth-child(odd){transform:rotate(-.5deg)}
:root[data-skin="poster"] .collage .media:nth-child(even),
:root[data-skin="poster"] .grid-3 .media:nth-child(even),
:root[data-skin="poster"] .grid-4 .media:nth-child(even){transform:rotate(.5deg)}
/* full-bleed and hero panels stay square to the page */
:root[data-skin="poster"] .bleed .media,
:root[data-skin="poster"] .hero__media .media,
:root[data-skin="poster"] .media--band{transform:none;box-shadow:none}
:root[data-skin="poster"] .igstrip__grid a{box-shadow:none}

/* ── the studio / retainers pair ── */
:root[data-skin="poster"] .duo__cell{box-shadow:var(--hard)}
:root[data-skin="poster"] .duo__cell:nth-child(odd){transform:rotate(-.4deg)}
:root[data-skin="poster"] .duo__cell:nth-child(even){transform:rotate(.4deg)}

/* ── reviews ── nav buttons become square stamps */
:root[data-skin="poster"] .reviews__nav button{
  border:var(--ink-w) solid var(--ink);box-shadow:4px 4px 0 var(--ink)}
:root[data-skin="poster"] .reviews__nav button:active{transform:translate(4px,4px);box-shadow:none}

/* ── forms ── inputs printed, not soft */
:root[data-skin="poster"] input[type=text],
:root[data-skin="poster"] input[type=email],
:root[data-skin="poster"] input[type=tel],
:root[data-skin="poster"] select,
:root[data-skin="poster"] textarea{
  border:var(--ink-w) solid var(--ink);box-shadow:4px 4px 0 var(--ink);background:var(--white)}
:root[data-skin="poster"] input:focus,
:root[data-skin="poster"] select:focus,
:root[data-skin="poster"] textarea:focus{
  outline:none;box-shadow:4px 4px 0 var(--accent);border-color:var(--accent)}

/* ── the panels I added ── they should obey the skin they switch on */
:root[data-skin="poster"] .changes__panel,
:root[data-skin="poster"] .palette__panel{
  border:var(--ink-w) solid var(--ink);box-shadow:var(--hard)}
:root[data-skin="poster"] .changes__toggle,
:root[data-skin="poster"] .palette__toggle{
  border:var(--ink-w) solid var(--ink);box-shadow:4px 4px 0 var(--ink)}
:root[data-skin="poster"] .changes__toggle:active,
:root[data-skin="poster"] .palette__toggle:active{transform:translate(4px,4px);box-shadow:none}

/* ── founders cards on /about ── */
:root[data-skin="poster"] .founders__card{
  border:var(--ink-w) solid var(--ink);border-radius:0;box-shadow:var(--hard)}
:root[data-skin="poster"] .founders__card--left{transform:rotate(-.6deg)}
:root[data-skin="poster"] .founders__card--right{transform:rotate(.6deg)}

/* ── steps / values blocks ── */
:root[data-skin="poster"] .step,
:root[data-skin="poster"] .values > *{
  border:var(--ink-w) solid var(--ink);border-radius:0;padding:1.15rem;
  box-shadow:4px 4px 0 var(--ink);background:var(--white)}

/* motion off: keep every keyline and shadow, drop only the tilt and the press */
@media (prefers-reduced-motion:reduce){
  :root[data-skin="poster"] .menu-tile,
  :root[data-skin="poster"] .duo__cell,
  :root[data-skin="poster"] .founders__card,
  :root[data-skin="poster"] .collage .media,
  :root[data-skin="poster"] .grid-3 .media,
  :root[data-skin="poster"] .grid-4 .media{transform:none}
}

/* small screens: lighter keylines, shorter throw, no tilt (it costs width) */
@media (max-width:560px){
  :root[data-skin="poster"] .menu-tile,
  :root[data-skin="poster"] .duo__cell,
  :root[data-skin="poster"] .founders__card,
  :root[data-skin="poster"] .collage .media,
  :root[data-skin="poster"] .grid-3 .media,
  :root[data-skin="poster"] .grid-4 .media{transform:none}
  :root[data-skin="poster"] .step,
  :root[data-skin="poster"] .values > *,
  :root[data-skin="poster"] input[type=text],
  :root[data-skin="poster"] input[type=email],
  :root[data-skin="poster"] input[type=tel],
  :root[data-skin="poster"] select,
  :root[data-skin="poster"] textarea{box-shadow:3px 3px 0 var(--ink)}
}
