/* tokens.css */
/* ---------- Fonts (self-hosted, OFL) ---------- */
@font-face {
  font-family: "Instrument Serif";
  src: url("/fonts/instrument-serif-400-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
/* Body: Quicksand (v2 frames: double-storey a, single-storey g; widths within 2% of the frame text) */
@font-face {
  font-family: "Quicksand";
  src: url("/fonts/quicksand-var-latin.woff2") format("woff2");
  font-weight: 400 600; font-style: normal; font-display: swap;
}
/* Metric-matched fallbacks so the swap doesn't reflow text (width ratios measured in Chrome) */
@font-face { font-family: "KD Serif Fallback"; src: local("Times New Roman"), local("Times"); size-adjust: 82%; }
@font-face { font-family: "KD Sans Fallback"; src: local("Arial"), local("Helvetica"); size-adjust: 106.6%; ascent-override: 93.8%; descent-override: 23.5%; line-gap-override: 0%; }

/* ---------- Tokens (read from the v2 Figma frames, 1440 px wide) ---------- */
:root {
  --cream: #F2EDDF;
  --magenta: #B40069;      /* hero rule, hamburger, K logo, footer arch */
  --k-stroke: #B0167F;
  --plum: #48284B;         /* headings and body text */
  --plum-deep: #331037;    /* portfolio arrow, carousel dots */
  --night-top: #200A22;    /* footer gradient: top ... */
  --night-bottom: #2F0F33; /* ... to 437 px below the arch line */
  --ink: #000;
  --placeholder: #D9D9D9;
  --btn-plum: #331037;     /* v4 buttons */
  --btn-magenta: #780C55;
  --cream-ink: #F2EDDF;    /* text on the dark footer */

  --serif: "Instrument Serif", "KD Serif Fallback", "Times New Roman", serif;
  --sans: "Quicksand", "KD Sans Fallback", Arial, sans-serif;

  /* Design unit: 1px at >= 1440 wide, scales down linearly to the tablet breakpoint.
     Uses the page container width (cqw) so a desktop scrollbar never causes overflow. */
  --u: min(1px, 100cqw / 1440);
  /* Viewport-based unit for fixed elements (outside the page container). */
  --vu: min(1px, 100vw / 1440);
  /* Type and buttons run a little smaller than the frames (client: "everything is just too big"):
     --ut = --u x --ts. Layout, cards and illustrations keep plain --u so nothing moves. */
  --ts: .88;
  --ut: calc(var(--u) * var(--ts));

  --radius-card: 9px;
  --radius-input: 6px;
  --radius-popup: 17px;

  --ease: cubic-bezier(.2, .7, .2, 1);
  --t-fast: 180ms;
  --t-med: 600ms;

  --gutter: 16px;
}

/* base.css */
/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; background: var(--cream); }
html:has(dialog[open]) { overflow: hidden; }
body {
  margin: 0; background: var(--cream); color: var(--plum);
  font: 500 18px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}
@supports (overflow-x: clip) { body { overflow-x: clip; } }
img, picture, video, canvas, svg { display: block; max-width: 100%; }
a { color: inherit; }
h1, h2, h3, p { margin: 0; }
h1, h2, h3 { font-family: var(--serif); font-weight: 400; color: var(--plum); line-height: 1.05; }
button, input { font: inherit; color: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 2px solid var(--magenta); outline-offset: 3px; }

.page { container-type: inline-size; }
.wrap { width: 100%; max-width: 1440px; margin-inline: auto; }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: fixed; left: 16px; top: 16px; z-index: 100; padding: 10px 16px;
  background: var(--plum); color: var(--cream); text-decoration: none; border-radius: 6px;
  transform: translateY(-200%); transition: transform var(--t-fast) var(--ease);
}
.skip-link:focus { transform: none; }

/* Placeholder for images that are not delivered yet: same box as the photo will fill */
.ph { display: block; width: 100%; height: 100%; background: var(--placeholder); }
.fill { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 760px) { body { font-size: 15px; } }

/* ---------- Buttons (v4 "Buttons" frame): 160 x 64, radius 10, cream serif label, drop shadow 3 4 4.3 #000 25%.
   Two colours: plum #331037 (default) and magenta #780C55 (.btn--magenta). Hover = the frame's raised state: up a
   little, the other colour, a longer shadow. Size runs with the type scale (--ut), like the rest of the controls. */
.btn {
  --btn-bg: var(--btn-plum); --btn-hover: var(--btn-magenta);
  display: inline-grid; place-items: center; box-sizing: border-box;
  /* The frame size on the type scale, with floors that shrink with the window between ~1100 and 768 so the buttons stay
     in proportion to the cards (fixed floors made them look large on tablets); never under a 44 px tap target */
  width: max(calc(160 * var(--ut)), clamp(104px, 9.2vw, 132px)); height: max(calc(64 * var(--ut)), clamp(44px, 3.6vw, 48px)); padding: 0 12px;
  border: 0; border-radius: calc(10 * var(--u)); background: var(--btn-bg); color: var(--cream);
  font: 400 max(calc(28 * var(--ut)), clamp(17px, 1.6vw, 22px)) / 1 var(--serif); letter-spacing: -.01em; white-space: nowrap; text-decoration: none; cursor: pointer;
  box-shadow: 3px 4px 4.3px rgba(0, 0, 0, .25);
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.btn--magenta { --btn-bg: var(--btn-magenta); --btn-hover: var(--btn-plum); }
@media (hover: hover) {
  .btn:hover { background-color: var(--btn-hover); transform: translateY(-3px); box-shadow: 4px 9px 12px rgba(0, 0, 0, .22); }
}
.btn:focus-visible { outline: 2px solid var(--magenta); outline-offset: 3px; box-shadow: 0 0 0 2px var(--cream), 3px 4px 4.3px rgba(0, 0, 0, .25); }
.btn:active { transform: translateY(1px); box-shadow: 1px 1px 2px rgba(0, 0, 0, .3); }
.btn[disabled] { cursor: progress; opacity: .7; transform: none; }
@media (max-width: 760px) { .btn { height: 46px; min-height: 46px; min-width: 120px; padding: 0 18px; width: auto; font-size: 21px; border-radius: 9px; } }

.text-link { text-decoration: none; background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size var(--t-fast) var(--ease); }
.text-link:hover, .text-link:focus-visible { background-size: 100% 1px; }

/* ---------- Photo card (About Recent Projects, Shop, product "While you're browsing", Home Recent Projects) ---------- */
.card {
  display: block; position: relative; aspect-ratio: 369 / 523; border-radius: calc(9 * var(--u)); overflow: hidden;
  background: var(--placeholder); text-decoration: none;
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.card picture, .card img { width: 100%; height: 100%; }
.card img { object-fit: cover; transition: transform 700ms var(--ease); }
@media (hover: hover) {
  a.card:hover { transform: translateY(-3px); box-shadow: 0 16px 30px -22px rgba(72, 40, 75, .7); }
  a.card:hover img { transform: scale(1.025); }
}
a.card:active { transform: scale(.99); }
@media (max-width: 760px) { .card { border-radius: 9px; } }

/* header.css */
/* ---------- Hamburger (v2 frames: 3 bars 68x3, 8 apart (rows 48/59/70), x 1299-1367 at 1440) ----------
   Round 3 (client: "menu feels too big on desktop"): desktop draws 46x2 bars 7 apart, centred on the frame's
   stack (row 60.5), same right edge. Phones keep their own values (below). */
.menu-btn {
  --bw: max(28px, calc(46 * var(--vu)));
  --bh: 2px;
  --bg: max(6px, calc(7 * var(--vu)));
  --pad: 10px;
  position: fixed; z-index: 30;
  top: calc(max(14px, 50.5 * var(--vu)) - var(--pad));
  right: calc(max(16px, 73 * var(--vu)) - var(--pad));
  display: grid; gap: var(--bg); padding: var(--pad);
  background: transparent; border: 0; border-radius: 12px;
  transition: background-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
/* Tap/click target at least 44 x 44 on every width, without changing what is drawn */
.menu-btn::before {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: max(100%, 44px); height: max(100%, 44px); transform: translate(-50%, -50%);
}
.menu-btn__bar {
  display: block; width: var(--bw); height: var(--bh); background: var(--magenta); border-radius: 0;
  transition: transform var(--t-fast) var(--ease);
}
@media (hover: hover) {
  .menu-btn:hover .menu-btn__bar:nth-child(1) { transform: translateX(-4px); }
  .menu-btn:hover .menu-btn__bar:nth-child(3) { transform: translateX(4px); }
}
.menu-btn:active { transform: scale(.96); }
/* Once the page scrolls, give the button a cream backing so it stays visible over photos and the dark footer */
.is-scrolled .menu-btn { background: rgba(242, 237, 223, .94); box-shadow: 0 6px 20px -12px rgba(72, 40, 75, .6); }

/* ---------- Small K logo, inner pages (v2: ink 48x52 at 71,29; #B40069). Scrolls with the page. ---------- */
.site-logo {
  position: absolute; z-index: 20; left: max(16px, calc(71 * var(--vu))); top: max(14px, calc(29 * var(--vu)));
  width: max(34px, calc(48 * var(--vu))); display: block; border-radius: 4px;
  transition: transform var(--t-fast) var(--ease);
}
.site-logo svg { width: 100%; height: auto; overflow: visible; }
@media (hover: hover) { .site-logo:hover { transform: rotate(-4deg) scale(1.04); } }

/* ---------- Menu (full-screen <dialog>) ---------- */
.menu {
  width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0;
  background: var(--cream); color: var(--plum);
}
.menu::backdrop { background: var(--cream); }
/* The menu always fits the screen (v4 bug: on short desktop windows the list ran under the bottom strip): type and
   spacing scale with the window height as well as its width, the list's row may shrink (minmax(0, 1fr)) and then
   scrolls inside itself, the bottom strip stays compact. */
.menu[open] { display: grid; grid-template-rows: minmax(0, 1fr) auto; }
.menu__close {
  position: absolute; top: calc(max(14px, 48 * var(--vu)) - 10px); right: calc(max(16px, 73 * var(--vu)) - 10px);
  width: calc(max(28px, 46 * var(--vu)) + 20px); height: max(44px, calc(max(28px, 46 * var(--vu)) * .45 + 20px));
  background: none; border: 0; padding: 0; border-radius: 12px;
}
.menu__close::before, .menu__close::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: min(34px, 70%); height: 2px;
  background: var(--magenta); transform: translate(-50%, -50%) rotate(45deg);
}
.menu__close::after { transform: translate(-50%, -50%) rotate(-45deg); }
.menu__nav { align-self: center; padding: clamp(64px, 12vh, 96px) clamp(24px, 9vw, 140px) clamp(12px, 3vh, 24px); overflow-y: auto; overscroll-behavior: contain; max-height: 100%; }
.menu__list, .menu__sub { list-style: none; margin: 0; padding: 0; }
.menu__list > li + li { margin-top: clamp(2px, 1vh, 12px); }
.menu__link {
  font-family: var(--serif); font-size: clamp(28px, min(4.6vw, 7.2vh), 66px); line-height: 1.1; color: var(--plum);
  text-decoration: none; display: inline-block; transition: color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.menu__link:hover, .menu__link:focus-visible { color: var(--magenta); transform: translateX(6px); }
.menu__link[aria-current="page"] { color: var(--magenta); }
.menu__sub { display: flex; flex-wrap: wrap; gap: 4px 28px; margin: clamp(0px, .5vh, 4px) 0 clamp(4px, 1.2vh, 10px) 4px; }
.menu__sublink { font-size: clamp(15px, min(1.4vw, 2.6vh), 20px); letter-spacing: .04em; text-decoration: none; color: var(--plum); }
.menu__sublink:hover, .menu__sublink:focus-visible { color: var(--magenta); }
.menu__foot {
  display: flex; flex-wrap: wrap; gap: 8px 28px; align-items: center; justify-content: space-between;
  padding: clamp(12px, 2.4vh, 20px) clamp(24px, 9vw, 140px) clamp(14px, 3vh, 28px); border-top: 4px solid var(--magenta);
  font-size: 13px; letter-spacing: .08em; text-transform: uppercase;
}
.menu__signup { background: none; border: 0; padding: 0; color: var(--plum); text-transform: uppercase; letter-spacing: .08em; }
.menu__signup:hover, .menu__signup:focus-visible { color: var(--magenta); }
.menu__email { color: var(--plum); text-transform: none; letter-spacing: .02em; }
.menu__copy { flex-basis: 100%; opacity: .7; font-size: 13px; }
.menu .socials { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 22px; }
@media (prefers-reduced-motion: no-preference) {
  .menu[open] { animation: menu-in 260ms var(--ease); }
  @keyframes menu-in { from { opacity: 0; } to { opacity: 1; } }
  .menu[open] .menu__list > li { animation: menu-item-in 420ms var(--ease) both; }
  .menu[open] .menu__list > li:nth-child(2) { animation-delay: 40ms; }
  .menu[open] .menu__list > li:nth-child(3) { animation-delay: 80ms; }
  .menu[open] .menu__list > li:nth-child(4) { animation-delay: 120ms; }
  .menu[open] .menu__list > li:nth-child(5) { animation-delay: 160ms; }
  @keyframes menu-item-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
}

/* Phones: a lighter hamburger and logo (client: delicate, not chunky) */
@media (max-width: 760px) {
  .menu-btn { --bw: 28px; --bh: 2px; --bg: 6px; top: calc(max(14px, 48 * var(--vu)) - var(--pad)); }
  .menu__close { width: 48px; height: 44px; top: calc(max(14px, 48 * var(--vu)) - 14px); } /* X drawn where it was (36 px box), 44 px target */
  .menu__close::before, .menu__close::after { width: 26px; height: 2px; }
  .site-logo { width: 30px; }
  .menu__nav { padding-top: 80px; }
  .menu__sub { gap: 2px 20px; }
  .menu__sublink { font-size: 15px; }
}

/* hero.css */
/* ---------- Hero (video + inline K; files in /hero/, unchanged) ----------
   v2 landing frame: the 1440 x 1080 hero box is scaled 0.61476 and placed at (291.79, 16.69) of the 1440 frame;
   the 5 px magenta rule (the box's baked 8 px rule, y 920-928 -> 582.26-587.18) runs from x 130 to 1309 only.
   The whole composition is a 1440 x 698 stage (698 = the card row's top) scaled by --hs so it always fits the
   screen: --hs = min(width / 1440, height / 698). It may grow past 1440 like the old full-bleed hero did.
   The box fades out over its outer edges (sides 24, top 12, bottom 20 frame px; the art never reaches them),
   so the decoded video cream and rule blend into the page cream and the CSS rule under it, never a step. */
.hero-band {
  --hs: min(100cqw / 1440, 100svh / 698);
  position: relative; height: calc(698 * var(--hs)); overflow: hidden;
}
@supports not (height: 100svh) { .hero-band { --hs: min(100cqw / 1440, 100vh / 698); } }
.hero-stage { position: absolute; top: 0; left: 50%; width: calc(1440 * var(--hs)); height: 100%; margin-left: calc(-720 * var(--hs)); }
/* SVG so the rule's fractional top and bottom edges anti-alias exactly like the scaled poster's own rule */
.hero-rule { position: absolute; left: calc(130 * var(--hs)); width: calc(1179 * var(--hs)); top: calc(578 * var(--hs)); height: calc(14 * var(--hs)); max-width: none; }

.kd-hero {
  --fx: calc(24 * var(--hs)); --ft: calc(12 * var(--hs)); --fb: calc(20 * var(--hs));
  position: absolute; left: calc(291.79 * var(--hs)); top: calc(16.69 * var(--hs));
  width: calc(885.25 * var(--hs)); aspect-ratio: 1440 / 1080; overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--fx), #000 calc(100% - var(--fx)), transparent),
    linear-gradient(to bottom, transparent, #000 var(--ft), #000 calc(100% - var(--fb)), transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(to right, transparent, #000 var(--fx), #000 calc(100% - var(--fx)), transparent),
    linear-gradient(to bottom, transparent, #000 var(--ft), #000 calc(100% - var(--fb)), transparent);
  mask-composite: intersect;
}
.kd-hero__poster, .kd-hero__poster img, .kd-hero__video { position: absolute; inset: 0; width: 100%; height: 100%; display: block; max-width: none; }
.kd-hero__poster img, .kd-hero__video { object-fit: cover; }
/* K: Figma origin (426, 165), 588 x 634 in the 1440 x 1080 hero */
.kd-hero__k { position: absolute; left: 29.5833%; top: 15.2778%; width: 40.8333%; height: auto; max-width: none; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .kd-hero__video { display: none; } }

/* Phones: the box spans the full width (at 0.61476 the K would be ~98 px wide); its baked rule runs edge to edge */
@media (max-width: 760px) {
  .hero-band { height: 75cqw; }
  .hero-stage { position: absolute; inset: 0; width: auto; margin: 0; }
  .hero-rule { display: none; }
  .kd-hero {
    --fb: 14px; left: 0; top: 0; width: 100%;
    -webkit-mask-image: linear-gradient(to bottom, #000, #000 calc(100% - var(--fb)), transparent);
    mask-image: linear-gradient(to bottom, #000, #000 calc(100% - var(--fb)), transparent);
  }
}

/* Phones, intro (paid add-on, 2 Oct): the page opens with the hero large and centred on a full screen of cream;
   as you scroll it shrinks and rises into its place at the top (the state above). The band is one screen tall,
   the stage sticks to the top while the band scrolls past, so at the end of that run (100svh - 75cqw of scroll)
   the hero sits exactly where it sits without the intro and the cards follow right under it.
   --e (0 -> 1, eased) is set by hero.js on scroll; the first paint is the large state (--e 0) from CSS alone, so
   nothing jumps when the script arrives. Without JS or with reduced motion: no intro. */
@media (max-width: 760px) and (prefers-reduced-motion: no-preference) {
  .js .hero-band--intro { --S: 1.4; --e: 0; height: 100svh; overflow: clip; }
  @supports not (height: 100svh) { .js .hero-band--intro { height: 100vh; } }
  .js .hero-band--intro .hero-stage { position: sticky; inset: 0 auto auto; height: 75cqw; }
  .js .hero-band--intro .kd-hero {
    transform-origin: 50% 0;
    transform: translateY(calc((100svh - 75cqw * var(--S)) / 2 * (1 - var(--e)))) scale(calc(var(--S) - (var(--S) - 1) * var(--e)));
    will-change: transform;
  }
}

/* "Scroll to enter" (round 3): centred at the bottom of the hero band (desktop: in the cream under the hero box;
   phones: the bottom of the full-screen intro only). Absolutely positioned, so it never shifts layout. hero.js
   sets .is-gone on the first scroll and removes it only at scroll position 0. Needs JS (it can't hide without it). */
.hero-enter {
  display: none; position: absolute; left: 0; right: 0; bottom: calc(16 * var(--hs)); z-index: 2; margin: 0;
  text-align: center; font: 400 17px/1 var(--serif); letter-spacing: .03em; color: var(--plum);
  pointer-events: none; transition: opacity 500ms var(--ease);
}
.js .hero-enter { display: block; }
.hero-enter.is-gone { opacity: 0; }
.hero-enter span { display: inline-block; opacity: .8; }
@media (prefers-reduced-motion: no-preference) {
  .hero-enter span { animation: hero-enter-pulse 2.8s ease-in-out infinite; }
  @keyframes hero-enter-pulse { 0%, 100% { opacity: .8; } 50% { opacity: .4; } }
}
@media (prefers-reduced-motion: reduce) { .hero-enter { transition: none; } }
@media (max-width: 760px) { .js .hero-enter { display: none; } }
@media (max-width: 760px) and (prefers-reduced-motion: no-preference) {
  .js .hero-band--intro .hero-enter { display: block; bottom: calc(22px + env(safe-area-inset-bottom, 0px)); font-size: 16px; }
}

/* The rule grows out from the flower (round 3, route b: the video keeps its baked rule, because the hanging petal
   must stay in front of it and moves across it). Cream covers hide the rule's rows outside the petal's sweep
   (box x 492.5-747.5 of 1440; the petal spans 498.5-741.5 over the loop) and shrink outward when the hero settles
   (hero.js adds .is-grown to the band). They cover 1 px beyond the rule's anti-aliased rows; stems stop at the
   rule's top edge (v2.6.1), so nothing but rule is hidden. Reduced motion or no JS: no covers, the line is there.
   Desktop: in the stage (above the box and the CSS rule; rule rows 582.27-587.61). Phones: inside the box (rule
   rows 920-928 of 1080), so they follow the intro's scale. */
.hero-cover, .kd-hero__cover {
  display: none; position: absolute; z-index: 1; background: var(--cream); pointer-events: none;
  transition: transform 1600ms cubic-bezier(.3, .6, .2, 1);
}
.hero-cover--l, .kd-hero__cover--l { transform-origin: 0 50%; }
.hero-cover--r, .kd-hero__cover--r { transform-origin: 100% 50%; }
.is-grown .hero-cover, .is-grown .kd-hero__cover { transform: scaleX(0); }
.hero-cover { top: calc(582.27 * var(--hs) - 1px); height: calc(5.34 * var(--hs) + 2px); }
.hero-cover--l { left: calc(128 * var(--hs)); width: calc(466.55 * var(--hs)); }   /* 128 -> 594.55 (box x 492.5) */
.hero-cover--r { left: calc(751.32 * var(--hs)); width: calc(559.68 * var(--hs)); } /* box x 747.5 -> 1311 */
.kd-hero__cover { top: calc(85.1852% - 1px); height: calc(0.7407% + 4px); } /* 3 px past the rule rows below: at 1.4x the video's softened rule bottom edge showed as a pink hairline */
.kd-hero__cover--l { left: 0; width: 34.2014%; }
.kd-hero__cover--r { left: 51.9097%; right: 0; }
@media (prefers-reduced-motion: no-preference) {
  .js .hero-cover { display: block; }
  @media (max-width: 760px) { .js .hero-cover { display: none; } .js .kd-hero__cover { display: block; } }
}

/* home.css */
/* ---------- Home (v4 "Landing Page" frame, 1440 x 3558) ----------
   Section tops in the frame: hero stage 0-698, cards row 698-1404, word band 1404-1553, Portfolio 1553-2325.17,
   sign-up band 2325.17-2798.64, Recent Projects 2798.64-3265, footer 3265. Inside each section the boxes are her
   Figma boxes, measured from its top (design px; --u = 1 px at 1440). */
.featured, .pf, .hrecent { position: relative; max-width: 1440px; margin-inline: auto; }

/* ---------- Cards over the collage (cards 279 x 395 at y 754, x 296 / 596 / 896; collage 1031 x 447.45 at
   (190, 784); labels 32 px design (ink top 1079); Shop Now 160 x 64 at (642, 1231)) ---------- */
.featured { height: calc(706 * var(--u)); }
.featured__collage { position: absolute; z-index: 0; left: calc(190 * var(--u)); top: calc(86 * var(--u)); width: calc(1031 * var(--u)); pointer-events: none; }
.featured__collage img { width: 100%; height: auto; }
.featured__car { position: absolute; z-index: 1; left: calc(296 * var(--u)); top: calc(56 * var(--u)); }
.featured__grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, calc(279 * var(--u))); column-gap: calc(21 * var(--u)); }
.fcard {
  display: block; position: relative; aspect-ratio: 279 / 395; border: 1px solid var(--cream); border-radius: calc(7.3 * var(--u)); overflow: hidden;
  color: var(--plum-deep); text-decoration: none;
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.fcard__img { position: absolute; inset: 0; }
.fcard__img picture, .fcard__img img { width: 100%; height: 100%; }
.fcard__img img { object-fit: cover; transition: transform 700ms var(--ease); }
/* the card's own fill: clear at the top, solid cream 84% down (fitted to the frame), the label on the cream */
.fcard::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to bottom, rgba(242, 237, 223, 0), var(--cream) 84%); }
.fcard__label { position: absolute; z-index: 1; left: 0; right: 0; top: calc(318 * var(--u)); text-align: center; font: 400 calc(43 * var(--ut)) / 1.2 var(--serif); letter-spacing: -.01em; }
@media (hover: hover) {
  a.fcard:hover { transform: translateY(-3px); box-shadow: 0 16px 30px -22px rgba(72, 40, 75, .7); }
  a.fcard:hover img { transform: scale(1.025); }
}
a.fcard:active { transform: scale(.99); }
a.fcard:focus-visible { outline: 2px solid var(--magenta); outline-offset: 3px; }
.featured__dots { display: none; }
.shop-now { position: absolute; z-index: 2; top: calc(533 * var(--u)); left: calc(4 * var(--u)); right: 0; margin-inline: auto; } /* centred on x 722 at any button width */

/* ---------- Word band (#1F0A22, 149 tall; text #741957, 34 px design with 6% tracking, justified over two lines
   from x 19, ink top 1436). Sized to the frame's line length, so it keeps the frame's two lines. ---------- */
.words { background: #1F0A22; height: calc(149 * var(--u)); overflow: hidden; }
.words__text {
  max-width: 1440px; margin: 0 auto; padding: calc(30 * var(--u)) calc(4 * var(--u)) 0 calc(19 * var(--u));
  color: #741957; font: 400 calc(41.3 * var(--u)) / .963 var(--serif); letter-spacing: .06em;
  text-align: justify; text-align-last: justify;
}

/* ---------- Portfolio (heading 48 px design, ink top 1630, centred on x 704.5; the rule x 130-1309 at 1932;
   front piece 614 x 468 at (425, 1715) with a soft shadow, the pieces behind 520 x 396 at (239, 1757) and
   (709, 1757); Learn More / Get in touch 160 x 64 at (550 / 757, 2249)). The stack moves with transforms: every
   piece has the front box; behind = moved out and scaled 0.8469. ---------- */
.pf { height: calc(772.17 * var(--u)); }
.pf__title { position: absolute; left: calc(345 * var(--u)); width: calc(719 * var(--u)); top: calc(66 * var(--u)); text-align: center; font-size: calc(61 * var(--ut)); line-height: 1.2; letter-spacing: -.01em; color: rgba(51, 16, 55, .9); }
.pf__stage { position: absolute; inset: 0; }
.pf__rule { position: absolute; left: calc(130 * var(--u)); top: calc(379 * var(--u)); width: calc(1179 * var(--u)); height: calc(5 * var(--u)); min-height: 3px; background: var(--magenta); }
.pf__stack { list-style: none; margin: 0; padding: 0; }
.pf__slide {
  --x: 0px; --y: 0px; --s: 1;
  position: absolute; z-index: 1; left: calc(425 * var(--u)); top: calc(162 * var(--u)); width: calc(614 * var(--u)); aspect-ratio: 614 / 468;
  background: var(--placeholder); opacity: 0; visibility: hidden; transform-origin: 50% 50%;
  transform: translate(var(--x), var(--y)) scale(var(--s));
  transition: transform 520ms var(--ease), opacity 400ms var(--ease), visibility 0s linear 520ms, box-shadow 520ms var(--ease);
}
.pf__slide[data-pos] { visibility: visible; opacity: 1; transition: transform 520ms var(--ease), opacity 400ms var(--ease), box-shadow 520ms var(--ease); }
.pf__slide[data-pos="front"] { z-index: 3; box-shadow: 0 4px 4px rgba(0, 0, 0, .25); }
.pf__slide[data-pos="prev"] { z-index: 2; --x: calc(-233 * var(--u)); --y: calc(6 * var(--u)); --s: .8469; }
.pf__slide[data-pos="next"] { z-index: 2; --x: calc(237 * var(--u)); --y: calc(6 * var(--u)); --s: .8469; }
.pf__link { display: block; width: 100%; height: 100%; }
.pf__link picture, .pf__link img { width: 100%; height: 100%; }
.pf__link img { object-fit: cover; }
.pf__slide:not([data-pos="front"]) .pf__link { pointer-events: none; }
.pf__link:focus-visible { outline: 2px solid var(--magenta); outline-offset: 3px; }
@media (hover: hover) { .pf__slide[data-pos="front"]:hover { box-shadow: 0 14px 28px -10px rgba(0, 0, 0, .35); } }
/* the visible parts of the two pieces behind are the previous / next buttons */
.pf__nav { position: absolute; z-index: 4; top: calc(204 * var(--u)); height: calc(396 * var(--u)); padding: 0; border: 0; background: none; cursor: pointer; border-radius: 4px; }
.pf__nav--prev { left: calc(239 * var(--u)); width: calc(186 * var(--u)); }
.pf__nav--next { left: calc(1039 * var(--u)); width: calc(190 * var(--u)); }
.pf__nav:focus-visible { outline: 2px solid var(--magenta); outline-offset: 3px; }
.pf__btns { position: absolute; left: 0; right: 0; top: calc(696 * var(--u)); display: flex; justify-content: center; gap: calc(207 * var(--u) - 160 * var(--ut)); padding-left: calc(27 * var(--u)); }

/* ---------- "Let's stay in touch!" (green strip #183A21 205 tall at 2476; plants as placed; heading 48 px design
   ink top 2504, line ink top 2550, field 445 x 53 at (491, 2579)) ---------- */
.band { position: relative; height: calc(473.47 * var(--u)); }
.band__strip { position: absolute; left: 0; right: 0; top: calc(150.83 * var(--u)); height: calc(205 * var(--u)); background: #183A21; }
.band__plant { position: absolute; z-index: 1; pointer-events: none; }
.band__plant img { width: 100%; height: auto; }
.band__plant--l { left: calc(50% + (220 - 720) * var(--u)); top: calc(36 * var(--u)); width: calc(346 * var(--u)); }
.band__plant--r { left: calc(50% + (851.5 - 720) * var(--u)); top: calc(34.5 * var(--u)); width: calc(349.5 * var(--u)); }
/* 445 wide in the frame, never narrower than 280 (tablets: the placeholder fits); centred where the frame centres it */
.band__body { --bw: max(calc(445 * var(--u)), 280px); position: absolute; z-index: 2; left: calc(50% + (713.5 - 720) * var(--u) - var(--bw) / 2); top: calc(170 * var(--u)); width: var(--bw); text-align: center; color: var(--cream); }
.band__title { padding-top: calc(4 * var(--u)); color: var(--cream); font-size: calc(46 * var(--ut)); line-height: 1.1; letter-spacing: -.01em; white-space: nowrap; }
.band__text { margin-top: calc(-2 * var(--u)); font: 400 max(13px, calc(16.2 * var(--ut))) / 1.2 var(--serif); }
.band .signup { position: absolute; left: 0; right: 0; top: calc(83.83 * var(--u)); text-align: left; }
.band .signup__input { height: calc(53 * var(--u)); min-height: 44px; background: var(--cream); border-radius: calc(6 * var(--u)); }
.band .signup__input:focus { background: #fff; box-shadow: none; outline: 2px solid var(--cream); outline-offset: 3px; } /* cream ring on the green (magenta is 1.9:1 there) */
.band .signup__msg { color: var(--cream); text-align: center; }
.band .signup__msg.is-error { color: #ffc9be; }
.band .signup.is-done .signup__msg { min-height: calc(53 * var(--u)); display: grid; place-items: center; font-size: calc(24 * var(--ut)); }
/* Tablets (761-1100): the type and field keep their minimum sizes while the strip scales down, so a message under the
   field would land below the strip, pale on cream. While a message shows, the strip reaches down under it (it is
   absolutely placed: nothing else moves). */
.band:has(.signup__msg:not(:empty)) .band__strip { height: max(calc(205 * var(--u)), 172px); }

/* ---------- Recent Projects ("Recent Projects" ink 136, 2842; cards 345 x 254 at y 2907, x 136 / 546 / 957;
   titles ink top 3172, centred under the cards) ---------- */
.hrecent { height: calc(466.36 * var(--u)); }
.hrecent__title { position: absolute; left: calc(134 * var(--u)); top: calc(34 * var(--u)); font-size: calc(49 * var(--ut)); line-height: 1.2; letter-spacing: -.01em; }
.hrecent__grid { list-style: none; margin: 0; padding: 0; position: absolute; left: calc(136 * var(--u)); top: calc(108.36 * var(--u)); display: grid; grid-template-columns: repeat(3, calc(345 * var(--u))); column-gap: calc(65.5 * var(--u)); }
.hrecent__card { display: block; text-decoration: none; color: var(--plum-deep); }
.hrecent__img { display: block; aspect-ratio: 345 / 254; border-radius: calc(10 * var(--u)); }
.hrecent__name { display: block; margin-top: calc(6 * var(--u)); text-align: center; font: 400 calc(26 * var(--ut)) / 1.2 var(--serif); letter-spacing: -.01em; }
@media (hover: hover) {
  .hrecent__card:hover .hrecent__img { transform: translateY(-3px); box-shadow: 0 16px 30px -22px rgba(72, 40, 75, .7); }
  .hrecent__card:hover .hrecent__img img { transform: scale(1.025); }
}
.hrecent__card:focus-visible { outline: none; }
.hrecent__card:focus-visible .hrecent__img { outline: 2px solid var(--magenta); outline-offset: 3px; }

/* ---------- Phones ---------- */
@media (max-width: 760px) {
  /* cards: a swipeable row (the next card peeking in) over the collage, dots under it */
  .featured { height: auto; padding: 28px 0 56px; overflow-x: clip; }
  .featured__collage { left: 50%; top: 40px; width: 136vw; margin-left: -68vw; }
  .featured__car { position: relative; left: auto; top: auto; }
  .featured__grid {
    display: flex; gap: 12px; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
    padding: 0 var(--gutter); scroll-padding-inline: var(--gutter); scrollbar-width: none;
  }
  .featured__grid::-webkit-scrollbar { display: none; }
  .featured__grid > li { flex: 0 0 64%; max-width: 280px; scroll-snap-align: start; }
  .fcard { border-radius: 8px; }
  .fcard__label { top: auto; bottom: 7%; font-size: 26px; }
  .featured__dots { display: flex; justify-content: center; margin-top: 10px; }
  .featured__dots .car__dot { width: 24px; height: 24px; }
  .featured__dots .car__dot::before { width: 8px; height: 8px; min-width: 8px; min-height: 8px; }
  .shop-now { position: relative; top: auto; left: auto; margin: 22px auto 0; display: grid; width: max-content; }

  .words { height: auto; }
  .words__text { padding: 16px var(--gutter) 18px; font-size: 19px; line-height: 1.12; text-align: center; text-align-last: center; }

  /* Portfolio: the same stack, its pieces behind peeking in from the screen edges */
  .pf { height: auto; padding: 52px 0 0; overflow-x: clip; }
  .pf__title { position: static; width: auto; font-size: 36px; }
  .pf__stage { position: relative; height: calc(64vw * 468 / 614 + 24px); margin-top: 18px; }
  .pf__rule { left: 0; right: 0; width: auto; top: 50%; height: 3px; margin-top: -1.5px; }
  .pf__slide { left: 18vw; top: 12px; width: 64vw; }
  .pf__slide[data-pos="prev"] { --x: -42vw; --y: 0px; --s: .8; }
  .pf__slide[data-pos="next"] { --x: 42vw; --y: 0px; --s: .8; }
  .pf__nav { top: 12px; height: calc(64vw * 468 / 614); }
  .pf__nav--prev { left: 0; width: 18vw; }
  .pf__nav--next { left: auto; right: 0; width: 18vw; }
  .pf__btns { position: static; gap: 12px; padding: 26px var(--gutter) 0; }

  /* Sign-up band: heading, line and field on the strip; the plants at the strip's ends, their lower half (which
     the desktop field covers) fading into the green */
  .band { height: auto; padding: 72px 0 28px; overflow-x: clip; }
  .band__strip { top: 72px; bottom: 28px; height: auto; }
  .band__plant { width: 150px; -webkit-mask-image: linear-gradient(#000 44%, transparent 55%); mask-image: linear-gradient(#000 44%, transparent 55%); }
  .band__plant--l { left: -64px; top: 25px; width: 150px; }
  .band__plant--r { left: auto; right: -64px; top: 24px; width: 152px; }
  .band__body { position: relative; left: auto; top: auto; width: auto; padding: 26px var(--gutter) 30px; }
  .band__title { font-size: 30px; white-space: normal; }
  .band__text { margin-top: 6px; font-size: 15px; }
  .band .signup { position: relative; top: auto; margin: 18px auto 0; max-width: 360px; }
  .band .signup__input { height: 46px; font-size: 15px; border-radius: 6px; }
  .band .signup__submit { width: 34px; height: 34px; margin-top: -17px; right: 6px; }
  .band .signup.is-done .signup__msg { min-height: 46px; font-size: 22px; }
  .band:has(.signup__msg:not(:empty)) .band__strip { height: auto; }

  .hrecent { height: auto; padding: 40px var(--gutter) 56px; }
  .hrecent__title { position: static; font-size: 30px; }
  .hrecent__grid { position: static; margin-top: 14px; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
  .hrecent__img { border-radius: 8px; }
  .hrecent__name { margin-top: 6px; font-size: 14px; line-height: 1.25; }
}
@media (max-width: 760px) and (prefers-reduced-motion: no-preference) {
  .js .pf__slide { transition-duration: 420ms; }
}

/* about.css */
/* ---------- About (v2 about frame, 1440 wide) ----------
   "About" ink at 139,231 (67 px); two paragraphs from ink top 317 at x 138 (Quicksand 14/21, plum);
   photo 614x468 at 685,178; rose (bounding box 1011x1121.5, turned 21.71 deg) at -317,358, behind;
   "Portfolio Highlights" ink right 1296, top 798 (56 px); image 738x523 at 137,881 (radius 9); arrow 44 px
   circle centred on the image's right edge at y 1139; name ink right 1296 top 929 (28 px), note from 972;
   "Recent Projects" ink 140,1536 (43 px); cards 345x254 at x 137/548/958, y 1598; footer arch at 2029. */
.about-intro, .hl, .recent { position: relative; z-index: 1; max-width: 1440px; margin-inline: auto; }
.about-intro { z-index: 2; } /* text + photo above the rose, which lives in .hl */

/* Rose, from the uncropped original: past the page's left edge at 1440 (wider screens show it whole). Pivot = the
   cut end of the main stem. It sits in .hl (top 358 of the page = 342 above .hl, which starts at 700) so on phones
   it follows the flow. */
.about-rose { position: absolute; z-index: 0; left: calc(-317 * var(--u)); top: calc(-342 * var(--u)); width: calc(1011 * var(--u)); pointer-events: none; }
.about-rose__sway { transform-origin: 36.5% 85.5%; will-change: transform; }
.about-rose img { width: 100%; height: auto; }

/* The intro grows with her text (the frame's two paragraphs fit in 700; hers run longer): the text column is in the
   flow, the photo stays where the frame puts it. 180 below the text keeps it clear of the rose, whose art starts
   147.5 above .hl (its box top 342 above, first petal 194.5 into it) and sways a little. */
.about-intro { min-height: calc(700 * var(--u)); padding: calc(224 * var(--u)) 0 calc(180 * var(--u)) calc(137 * var(--u)); }
.about-intro__text { position: relative; width: calc(492 * var(--u)); }
.about-intro__title { font-size: calc(67 * var(--ut)); line-height: 1; letter-spacing: -.01em; padding-left: calc(3 * var(--u)); }
.about-intro__body { margin-top: calc(21 * var(--u)); font-size: max(14px, calc(14 * var(--ut))); line-height: 1.5; color: var(--plum); white-space: pre-line; }
.about-intro__body + .about-intro__body { margin-top: 1.5em; }
.about-intro__photo { position: absolute; left: calc(685 * var(--u)); top: calc(178 * var(--u)); width: calc(614 * var(--u)); aspect-ratio: 614 / 468; background: var(--placeholder); overflow: hidden; }
.about-intro__photo picture, .about-intro__photo img { width: 100%; height: 100%; }
.about-intro__photo img { object-fit: cover; }

/* ---------- Portfolio Highlights ---------- */
.hl { padding-top: calc(93 * var(--u)); }
.hl__title { text-align: right; padding-right: calc(143 * var(--u)); font-size: calc(56 * var(--ut)); line-height: 1; letter-spacing: -.01em; }
.hl__title, .hl__body { position: relative; z-index: 1; }
/* min-height: a long caption makes the section taller instead of running into Recent Projects */
.hl__body { position: relative; min-height: calc(523 * var(--u)); margin-top: calc(38.7 * var(--u)); }
.hl__media { position: absolute; left: calc(137 * var(--u)); top: 0; width: calc(738 * var(--u)); height: calc(523 * var(--u)); touch-action: pan-y; }
.hl__stack { list-style: none; margin: 0; padding: 0; position: absolute; inset: 0; border-radius: calc(9 * var(--u)); overflow: hidden; background: var(--placeholder); }
.hl__item { position: absolute; inset: 0; opacity: 0; visibility: hidden; transition: opacity 450ms var(--ease), visibility 0s linear 450ms; }
.hl__item.is-current { opacity: 1; visibility: visible; transition: opacity 450ms var(--ease); }
.hl__open { display: block; width: 100%; height: 100%; padding: 0; border: 0; background: var(--placeholder); cursor: zoom-in; }
.hl__open picture, .hl__open img { width: 100%; height: 100%; }
.hl__open img { object-fit: cover; transition: transform 700ms var(--ease); }
@media (hover: hover) { .hl__open:hover img { transform: scale(1.02); } }
.hl__open:focus-visible { outline-offset: -4px; }
.hl__next {
  --b: max(44px, calc(44 * var(--u)));
  position: absolute; z-index: 2; right: calc(var(--b) / -2); top: calc(258 * var(--u) - var(--b) / 2);
  width: var(--b); height: var(--b);
  border: 0; border-radius: 50%; padding: 0; display: grid; place-items: center;
  background: var(--plum-deep); color: var(--cream); box-shadow: 0 3px 6px rgba(0, 0, 0, .28);
  transition: transform var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.hl__next svg { width: 56%; height: auto; transition: transform var(--t-fast) var(--ease); }
@media (hover: hover) { .hl__next:hover { background: var(--magenta); } .hl__next:hover svg { transform: translateX(2px); } }
.hl__next:active { transform: scale(.94); }
.hl__caps { position: relative; width: calc(310 * var(--u)); margin: 0 calc(143 * var(--u)) 0 auto; padding-top: calc(43 * var(--u)); text-align: right; }
.hl__name { font-size: calc(28 * var(--ut)); line-height: 1.2; letter-spacing: -.01em; }
.hl__note { margin-top: calc(10 * var(--u)); font-size: max(14px, calc(14 * var(--ut))); line-height: 1.5; white-space: pre-line; }
@media (prefers-reduced-motion: no-preference) {
  .hl__cap:not([hidden]) { animation: hl-cap-in 450ms var(--ease); }
  @keyframes hl-cap-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
}

/* ---------- Recent Projects ---------- */
.recent { padding: calc(131.5 * var(--u)) 0 calc(243.6 * var(--u)); } /* v4: cards at 1598, titles under them, footer top 2129 */
.recent__title { margin-top: calc(-6 * var(--u)); padding-left: calc(139 * var(--u)); font-size: calc(46 * var(--ut)); line-height: 1; letter-spacing: -.01em; }
.recent__grid { list-style: none; margin: calc(28 * var(--u)) 0 0; padding: 0 0 0 calc(137 * var(--u)); display: grid; grid-template-columns: repeat(3, calc(345 * var(--u))); column-gap: calc(65.5 * var(--u)); }
.recent__card { width: 100%; aspect-ratio: 345 / 254; border: 0; padding: 0; cursor: zoom-in; }
.recent__name { margin-top: calc(6 * var(--u)); text-align: center; font: 400 calc(26 * var(--ut)) / 1.2 var(--serif); letter-spacing: -.01em; color: var(--plum-deep); }

@media (max-width: 760px) {
  .about-intro { min-height: 0; padding: 84px var(--gutter) 0; }
  .about-intro__text, .about-intro__photo { position: relative; left: auto; top: auto; width: auto; }
  .about-intro__title { font-size: 40px; }
  .about-intro__body { margin-top: 14px; font-size: 14.5px; line-height: 1.6; }
  .about-intro__photo { margin-top: 28px; width: 100%; }
  .about-rose { width: 301px; top: -48px; left: -151px; }
  .hl { padding: 72px var(--gutter) 0; }
  .hl__title { font-size: 30px; padding-right: 0; }
  .hl__body { min-height: 0; margin-top: 14px; }
  .hl__media { position: relative; left: auto; width: 100%; height: auto; aspect-ratio: 738 / 523; }
  .hl__stack { border-radius: 9px; }
  .hl__next { --b: 38px; right: 10px; top: auto; bottom: 10px; }
  .hl__caps { width: auto; margin: 14px 0 0; padding-top: 0; }
  .hl__name { font-size: 22px; }
  .hl__note { font-size: 14px; }
  .recent { padding: 64px var(--gutter) 72px; }
  .recent__title { padding: 0; font-size: 30px; }
  .recent__grid { padding: 0; margin-top: 14px; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
  .recent__name { margin-top: 6px; font-size: 14px; line-height: 1.25; }
}

/* lightbox.css */
/* ---------- Portfolio lightbox (<dialog>) ---------- */
.lb {
  width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: 0; border: 0;
  background: rgba(38, 18, 40, .96); color: var(--cream); overflow: hidden;
}
.lb::backdrop { background: rgba(38, 18, 40, .6); }
.lb__stage { position: absolute; inset: 0; display: grid; padding: 72px 136px 40px; touch-action: pan-y; }
.lb__slide { margin: 0; min-height: 0; display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 22px; justify-items: center; }
.lb__slide[hidden] { display: none; }
/* One definite cell, so the picture's max-height: 100% resolves and it shrinks to fit above the caption (it used to
   keep its own height and run under the caption on laptop screens) */
.lb__media { min-height: 0; height: 100%; width: 100%; display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); place-items: center; }
.lb__media picture { display: contents; }
.lb__media source { display: none; } /* else the <source>s become grid rows and push the picture into an auto row */
.lb__media > *, .lb__media img { grid-area: 1 / 1; }
.lb__img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; border-radius: 6px; }
.lb__media .ph { height: 100%; width: auto; max-width: 100%; aspect-ratio: 369 / 523; border-radius: 9px; }
.lb__cap { text-align: center; max-width: 62ch; max-height: min(30svh, 280px); overflow-y: auto; overscroll-behavior: contain; padding: 0 4px; } /* a long note scrolls inside */
.lb__title { color: var(--cream); font-size: clamp(28px, 2.6vw, 38px); }
.lb__note { margin-top: 6px; font-size: 17px; line-height: 1.55; opacity: .85; white-space: pre-line; }
.lb__count { position: absolute; left: 28px; top: 24px; font-size: 14px; letter-spacing: .14em; opacity: .75; }
.lb__nav, .lb__close {
  position: absolute; z-index: 2; border: 0; display: grid; place-items: center; border-radius: 50%;
  background: var(--cream); color: var(--plum);
  transition: transform var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.lb__nav { top: 50%; width: 68px; height: 68px; margin-top: -34px; }
.lb__nav[hidden] { display: none; }
.lb__nav svg { width: 62%; }
.lb__nav--prev { left: 34px; }
.lb__nav--prev svg { transform: scaleX(-1); }
.lb__nav--next { right: 34px; }
.lb__close { top: 16px; right: 18px; width: 48px; height: 48px; }
.lb__close svg { width: 20px; height: 20px; }
@media (hover: hover) {
  .lb__nav:hover, .lb__close:hover { background: #fff; }
  .lb__nav--next:hover { transform: translateX(3px); }
  .lb__nav--prev:hover { transform: translateX(-3px); }
  .lb__close:hover { transform: rotate(90deg); }
}
.lb__nav:active { transform: scale(.94); }
/* cream focus ring on the dark viewer (magenta is 2.6:1 there) */
.lb :focus-visible { outline-color: var(--cream); }
@media (prefers-reduced-motion: no-preference) {
  .lb[open] { animation: fade-in 260ms var(--ease); }
  .lb__slide.is-entering { animation: lb-in 320ms var(--ease); }
  @keyframes lb-in { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: none; } }
}
@media (max-width: 760px) {
  .lb__stage { padding: 64px 16px 92px; }
  .lb__cap { max-height: 38svh; }
  .lb__nav { top: auto; bottom: 18px; margin-top: 0; width: 56px; height: 56px; }
  .lb__nav--prev { left: calc(50% - 72px); }
  .lb__nav--next { right: calc(50% - 72px); }
}

/* ---------- Video pieces: play badge on the thumbnail; the player is inserted when the slide opens ---------- */
.play-badge {
  position: absolute; left: 50%; top: 50%; width: 56px; height: 56px; margin: -28px 0 0 -28px; border-radius: 50%;
  display: grid; place-items: center; background: rgba(242, 237, 223, .92); color: var(--plum);
  box-shadow: 0 6px 18px -8px rgba(40, 18, 42, .6); pointer-events: none;
  transition: transform var(--t-fast) var(--ease);
}
.play-badge svg { width: 24px; height: 24px; margin-left: 3px; }
.hl__open, .recent__card { position: relative; }
.recent__card .play-badge { width: 40px; height: 40px; margin: -20px 0 0 -20px; }
.recent__card .play-badge svg { width: 18px; height: 18px; }
@media (hover: hover) { .hl__open:hover .play-badge, .recent__card:hover .play-badge { transform: scale(1.08); } }
.lb__media--play { position: relative; }
.lb__media--play .play-badge { width: 72px; height: 72px; margin: -36px 0 0 -36px; }
.lb__media--play.is-playing > :not(.lb__player) { display: none; }
.lb__player { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; border: 0; border-radius: 6px; background: #000; }
video.lb__player { width: 100%; height: 100%; object-fit: contain; background: transparent; }
iframe.lb__player { width: min(100%, calc((100svh - 220px) * 16 / 9)); height: auto; aspect-ratio: 16 / 9; }
[data-tall] iframe.lb__player { width: auto; height: 100%; aspect-ratio: 9 / 16; }
@media (max-width: 760px) { .play-badge { width: 44px; height: 44px; margin: -22px 0 0 -22px; } .play-badge svg { width: 20px; height: 20px; } }

/* shop.css */
/* ---------- Shop (v4 shop frame: "Art Shop" ink 560-850, top 295, 64 px design with 10% tracking, centred on 703.5;
   carnation 627.37 x 851.9 turned -20.89 deg, its bounding box (-291, -70)-(599, 950) cut by the frame's left and
   top edges = the 599 x 950 export at (0, 0), always on the screen's top-left corner; cards 369x523 from (110, 404);
   footer at 1279) ---------- */
.shop { position: relative; padding: calc(289 * var(--u)) 0 calc(308.4 * var(--u)); } /* v4: footer top at 1279 (three cards, as in the frame) */
.shop:has(.shop__grid--wide) { padding-bottom: calc(441.6 * var(--u)); } /* four across: shorter cards, same page length as before */
.shop__flower { position: absolute; z-index: 0; top: 0; left: 0; width: calc(599 * var(--u)); pointer-events: none; }
.shop__flower img { width: 100%; height: auto; }
.shop__wrap { position: relative; z-index: 1; }
.shop__title { text-align: center; padding-right: calc(33 * var(--u)); font-size: calc(79.7 * var(--ut)); line-height: 1; letter-spacing: .1em; color: rgba(51, 16, 55, .9); white-space: nowrap; }
.shop__grid {
  list-style: none; margin: calc(44.9 * var(--u)) 0 0; padding: 0 0 0 calc(110 * var(--u));
  display: grid; grid-template-columns: repeat(3, calc(369 * var(--u))); column-gap: calc(70 * var(--u));
}
/* 4+ products: four across (same outer margins as the three-card row), more wrap onto new rows */
.shop__grid--wide { grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: calc(40 * var(--u)); row-gap: calc(56 * var(--u)); padding-right: calc(110 * var(--u)); }
.shop-card { display: grid; align-content: start; }
.shop-card__label { margin-top: calc(14 * var(--u)); text-align: center; font-size: calc(28 * var(--ut)); letter-spacing: -.03em; line-height: 1.2; }
.shop-card__label a { text-decoration: none; color: var(--plum); background: linear-gradient(currentColor, currentColor) 50% 100% / 0 1px no-repeat; transition: background-size var(--t-fast) var(--ease); }
.shop-card:hover .shop-card__label a, .shop-card__label a:focus-visible { background-size: 100% 1px; }
@media (hover: hover) {
  .shop-card:hover a.card { transform: translateY(-3px); box-shadow: 0 16px 30px -22px rgba(72, 40, 75, .7); }
  .shop-card:hover a.card img { transform: scale(1.025); }
}

@media (max-width: 760px) {
  .shop, .shop:has(.shop__grid--wide) { padding: 96px var(--gutter) 80px; }
  .shop__flower { width: 44vw; top: 34px; } /* its top rows are empty, so it can sit below the K; the left cut stays on the screen edge */
  .shop__title { font-size: 44px; padding: 0 0 0 18vw; }
  .shop__grid, .shop__grid--wide { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 14px; padding: 0; margin-top: 48px; }
  .shop-card__label { font-size: 19px; margin-top: 8px; }
}

/* ---------- Product template (v2 "shop-individual" frame) ---------- */
.product { position: relative; max-width: 1440px; margin-inline: auto; padding: calc(216 * var(--u)) 0 calc(149.6 * var(--u)); } /* v4: footer top at 1440 */
/* Rose: 557x1011 at (883, 311), cut by the frame's right edge. It lives in .browse (311 = 505 above .browse, which
   starts at 816) so on phones it follows the flow. Wider than 1440 the page centres, so the box reaches out to the
   screen edge (the cut stays on it, never in open space). */
.product__rose { position: absolute; z-index: 0; right: min(0px, (1440px - 100cqw) / 2); top: calc(-505 * var(--u)); width: calc(557 * var(--u)); pointer-events: none; }
.product__rose img { width: 100%; height: auto; }
.product__top { position: relative; z-index: 2; display: grid; grid-template-columns: calc(449 * var(--u)) 1fr; column-gap: calc(97 * var(--u)); padding-left: calc(141 * var(--u)); }

/* Carousel: scroll-snap track (swipe on touch), dots, arrow keys on the focused track */
.car { position: relative; width: 100%; aspect-ratio: 449 / 600; border-radius: calc(9 * var(--u)); overflow: hidden; background: var(--placeholder); }
.car__track { display: flex; height: 100%; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; }
.car__track::-webkit-scrollbar { display: none; }
.car__track:focus-visible { outline: 2px solid var(--magenta); outline-offset: -4px; }
.car__slide { flex: 0 0 100%; height: 100%; scroll-snap-align: start; scroll-snap-stop: always; }
.car__slide picture, .car__slide img { width: 100%; height: 100%; }
.car__slide img { object-fit: cover; }
/* Each dot button is one 16 px pitch wide (24 px on phones, for touch); the visible 11 px dot is drawn inside */
.car__dots { position: absolute; left: 0; right: 0; bottom: calc(55 * var(--u) - 12px + 5.5 * var(--u)); display: flex; justify-content: center; }
.car__dot { position: relative; width: calc(16 * var(--u)); height: 24px; min-width: 12px; padding: 0; border: 0; background: none; border-radius: 6px; }
.car__dot::before {
  content: ""; position: absolute; left: 50%; top: 50%; width: calc(11 * var(--u)); height: calc(11 * var(--u)); min-width: 9px; min-height: 9px;
  border-radius: 50%; background: var(--plum-deep); transform: translate(-50%, -50%); transition: transform var(--t-fast) var(--ease);
}
.car__dot[aria-current="true"]::before { background: transparent; box-shadow: inset 0 0 0 1.5px var(--plum-deep); }
@media (hover: hover) { .car__dot:hover::before { transform: translate(-50%, -50%) scale(1.2); } }

.product__info { padding-top: calc(17 * var(--u)); }
.product__title { font-size: calc(50 * var(--ut)); line-height: 1; letter-spacing: -.01em; }
.product__text { margin-top: calc(25 * var(--u)); max-width: calc(566 * var(--u)); padding-left: calc(6 * var(--u)); font-size: max(15px, calc(19.5 * var(--ut))); line-height: 1.59; }

/* Two stacked 160x64 buttons. Same boxes in every state, so connecting Shopify moves nothing. */
.buy { margin-top: calc(35 * var(--u)); }
.product__actions { display: grid; justify-items: start; row-gap: calc(16 * var(--ut)); }
.product__actions[hidden] { display: none; }
.pbtn {
  display: grid; place-items: center; width: calc(160 * var(--ut)); height: calc(64 * var(--ut)); min-width: 132px; min-height: 48px; padding: 0 10px;
  border: 0; border-radius: calc(9 * var(--u)); background: var(--placeholder); color: var(--plum);
  font: 400 max(22px, calc(28 * var(--ut))) / 1 var(--serif); letter-spacing: -.01em; white-space: nowrap; text-decoration: none; cursor: pointer;
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
@media (hover: hover) { button.pbtn:hover { background: #d0cccd; transform: translateY(-2px); box-shadow: 0 8px 18px -10px rgba(72, 40, 75, .55); } }
button.pbtn:active { transform: scale(.98); box-shadow: none; }
.pbtn--soon { cursor: default; color: rgba(72, 40, 75, .7); font-size: max(19px, calc(24 * var(--ut))); }
.buy[data-loading] .buy__mount { min-height: 64px; border-radius: 9px; background: linear-gradient(90deg, rgba(217,217,217,.5), rgba(217,217,217,.9), rgba(217,217,217,.5)) 0 0 / 200% 100%; width: calc(160 * var(--ut)); }
@media (prefers-reduced-motion: no-preference) { .buy[data-loading] .buy__mount { animation: shimmer 1.4s linear infinite; } @keyframes shimmer { to { background-position: -200% 0; } } }
/* Shopify Buy Button JS renders in-page (iframe: false); these classes are its markup. Its product box is
   flattened into the actions grid so the order is: price, variant picker, Buy Now, Add to Cart (survives the
   SDK's re-renders when a variant changes). */
.buy__live .buy__mount, .buy__live .shopify-buy__product { display: contents; }
.buy__live .shopify-buy__product__price { order: 1; }
.buy__live .shopify-buy__option-select, .buy__live .shopify-buy__product__variant-selectors { order: 2; }
.buy__live .buy__now { order: 3; }
.buy__live .shopify-buy__btn-wrapper { order: 4; }
.buy--collection .buy__mount, .buy--collection .shopify-buy__product { display: block; }
.buy .shopify-buy__product__price { font: 400 28px/1.2 var(--serif); color: var(--plum); margin: 0; }
.buy .shopify-buy__product__compare-price { opacity: .6; text-decoration: line-through; margin-left: 8px; }
.buy .shopify-buy__option-select__label { display: block; font-size: 14px; letter-spacing: .12em; text-transform: uppercase; margin-bottom: 6px; color: var(--plum); }
.buy .shopify-buy__option-select__select { height: 48px; border: 1px solid rgba(72, 40, 75, .35); border-radius: 6px; background: var(--cream); color: var(--plum); padding: 0 12px; font: 500 16px var(--sans); }
.buy .shopify-buy__btn-wrapper { margin: 0; }
.buy .shopify-buy__btn { width: calc(160 * var(--ut)); height: calc(64 * var(--ut)); min-width: 132px; min-height: 48px; padding: 0 10px; border: 0; border-radius: calc(9 * var(--u)); background: var(--placeholder); color: var(--plum); font: 400 max(22px, calc(28 * var(--ut))) / 1 var(--serif); cursor: pointer; transition: transform var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease); }
.buy .shopify-buy__btn:hover { background: #d0cccd; transform: translateY(-2px); }
.buy .shopify-buy__btn[disabled] { opacity: .6; cursor: not-allowed; transform: none; }
.buy .shopify-buy__collection-products { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 20px; }
.buy .shopify-buy__product-img-wrapper img { border-radius: 9px; width: 100%; }
.buy .shopify-buy__product__title { font: 400 22px/1.2 var(--serif); color: var(--plum); margin: 8px 0 2px; }

/* While you're browsing... */
.browse { position: relative; z-index: 1; padding: calc(124.1 * var(--u)) 0 0 calc(141 * var(--u)); } /* v4: cards at (141, 1003) */
.browse__title, .browse__grid { position: relative; z-index: 1; }
.browse__title { margin-top: calc(-5 * var(--u)); font-size: calc(51 * var(--ut)); line-height: 1; letter-spacing: -.01em; padding-left: calc(3 * var(--u)); }
.browse__grid { list-style: none; margin: calc(23 * var(--u)) 0 0; padding: 0; display: grid; grid-template-columns: repeat(3, calc(345 * var(--u))); column-gap: calc(65.5 * var(--u)); }
.browse__card { aspect-ratio: 345 / 254; }
.browse__item { display: block; text-decoration: none; color: var(--plum-deep); }
.browse__name { display: block; margin-top: calc(6 * var(--u)); text-align: center; font: 400 calc(26 * var(--ut)) / 1.2 var(--serif); letter-spacing: -.01em; }
@media (hover: hover) {
  .browse__item:hover .card { transform: translateY(-3px); box-shadow: 0 16px 30px -22px rgba(72, 40, 75, .7); }
  .browse__item:hover .card img { transform: scale(1.025); }
}
.browse__item:focus-visible { outline: none; }
.browse__item:focus-visible .card { outline: 2px solid var(--magenta); outline-offset: 3px; }

@media (max-width: 760px) {
  .product { padding: 84px var(--gutter) 72px; }
  .product__top { grid-template-columns: minmax(0, 1fr); row-gap: 22px; padding: 0; }
  .car { border-radius: 9px; max-width: 340px; margin-inline: auto; }
  .car__dots { bottom: 12px; }
  .car__dot { width: 24px; height: 24px; }
  .car__dot::before { width: 10px; height: 10px; }
  .product__info { padding: 0; }
  .product__title { font-size: 32px; padding: 0; }
  .product__text { margin-top: 12px; max-width: none; padding: 0; font-size: 14.5px; line-height: 1.6; }
  .buy { margin-top: 20px; }
  .product__actions { grid-auto-flow: column; justify-content: start; column-gap: 10px; }
  .pbtn, .buy .shopify-buy__btn { width: auto; min-width: 116px; height: 44px; min-height: 44px; padding: 0 16px; border-radius: 8px; font-size: 19px; }
  .pbtn--soon { font-size: 17px; }
  .product__rose { width: 90px; top: 24px; right: calc(-1 * var(--gutter)); }
  .browse { padding: 56px 0 0; }
  .browse__title { padding-right: 70px; }
  .browse__title { font-size: 28px; padding: 0; }
  .browse__grid { margin-top: 12px; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
  .browse__name { margin-top: 6px; font-size: 14px; line-height: 1.25; }
}

/* footer.css */
/* ---------- Footer (v4 "new footer", every page) ----------
   Frame geometry (1440 wide): the footer box is 1185 wide, its left edge at x 156 on Home and x 148 on inner pages
   (both as drawn: the row sits a little right of centre). In it: the rule 1179 x 5 at top 149; the tulip at
   (405, 0) 302 wide on Home, (475, 50) 151.23 wide inside; links (16 px, black) at top 184: four centred in 109-wide
   boxes from x -3 (Home) / 67 (inner), then Contact / Shipping & Returns / Privacy Policy 50 apart from x 740 (Home,
   top 185) / 610 (inner, top 188); icons 30 x 30 at (1003 / 1064 / 1126, 107). The page ends 144 below the rule on
   Home and 103-122 below it inside (per frame), cutting the tulip's stem there. */
.site-footer {
  --fh: 259; --fl: 148;
  position: relative; height: calc(var(--fh) * var(--u)); overflow: hidden; color: #000;
}
.site-footer--home { --fh: 293; --fl: 156; }
.page-shop .site-footer { --fh: 252; }
.page-product .site-footer { --fh: 271; }
.page-about .site-footer { --fh: 263; }
.page-ack .site-footer { --fh: 258; }

.site-footer__in { position: absolute; top: 0; bottom: 0; left: 50%; width: calc(1185 * var(--u)); margin-left: calc((var(--fl) - 720) * var(--u)); }
.site-footer__rule { position: absolute; left: 0; top: calc(149 * var(--u)); width: calc(1179 * var(--u)); height: calc(5 * var(--u)); min-height: 3px; background: var(--magenta); }
.site-footer__tulip { position: absolute; z-index: 1; left: calc(475 * var(--u)); top: calc(50 * var(--u)); width: calc(151.23 * var(--u)); pointer-events: none; }
.site-footer--home .site-footer__tulip { left: calc(405 * var(--u)); top: 0; width: calc(302 * var(--u)); }
.site-footer__tulip img { width: 100%; height: auto; }

.site-footer__socials { position: absolute; z-index: 2; left: calc(1003 * var(--u)); top: calc(107 * var(--u)); list-style: none; margin: 0; padding: 0; display: flex; gap: calc(31 * var(--u)); }
.social { display: block; position: relative; color: var(--magenta); border-radius: 50%; transition: transform var(--t-fast) var(--ease), color var(--t-fast) var(--ease); }
.social svg { display: block; width: calc(30 * var(--u)); height: auto; min-width: 22px; }
a.social::after { content: ""; position: absolute; inset: max(-8px, calc(50% - 22px)); min-width: 44px; min-height: 44px; } /* 44 px tap target */
@media (hover: hover) { a.social:hover { transform: translateY(-2px); color: var(--plum-deep); } }
.social--soon { cursor: default; }

.site-footer__nav { position: absolute; z-index: 2; inset: 0; pointer-events: none; }
.site-footer__links { position: absolute; list-style: none; margin: 0; padding: 0; pointer-events: auto; font: 400 max(13px, calc(16 * var(--u))) / 1.17 var(--sans); margin-top: -4px; } /* -4: the links' 4 px padding */
.site-footer__links--l { left: calc(67 * var(--u)); top: calc(184 * var(--u)); display: grid; grid-auto-flow: column; grid-auto-columns: calc(109 * var(--u)); text-align: center; }
.site-footer__links--r { left: calc(610 * var(--u)); top: calc(188 * var(--u)); display: grid; grid-auto-flow: column; grid-template-columns: calc(59 * var(--u)) calc(161 * var(--u)) calc(109 * var(--u)); grid-auto-columns: max-content; column-gap: calc(50 * var(--u)); text-align: center; white-space: nowrap; }
.site-footer__links--r > li { display: flex; justify-content: center; } /* her box widths; a longer label overflows both sides evenly */
.site-footer--home .site-footer__links--l { left: calc(-3 * var(--u)); }
.site-footer--home .site-footer__links--r { left: calc(740 * var(--u)); top: calc(185 * var(--u)); }
.site-footer__link {
  display: inline-block; padding: 4px 0; color: #000; text-decoration: none;
  background: linear-gradient(currentColor, currentColor) 50% 100% / 0 1px no-repeat;
  transition: background-size var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
a.site-footer__link:hover, a.site-footer__link:focus-visible { color: var(--magenta); background-size: 100% 1px; }
.site-footer__link--soon { cursor: default; }

/* Small laptops (1001-1100): the 13 px minimum type no longer fits her 59 / 161 / 109 boxes, so the right group sizes
   to its words, 24 px apart at least, and ends at the rule's right end. Narrower than that the row can't clear the
   flower (Home's above all): the stacked layout below takes over from 1000. */
@media (min-width: 1001px) and (max-width: 1100px) {
  .site-footer__links--r, .site-footer--home .site-footer__links--r {
    left: auto; right: calc(6 * var(--u)); grid-template-columns: repeat(3, max-content); column-gap: max(24px, calc(46 * var(--u)));
  }
}

/* Phones and tablets (up to 1000): the same pieces stacked for a narrow screen. The rule runs gutter to gutter 86
   px down, the tulip stands on it in the middle (Home larger), the icons sit above the rule at the right, the links
   run in two columns either side of the stem, and the page bottom cuts the stem as on desktop. */
@media (max-width: 1000px) {
  .site-footer, .page-shop .site-footer, .page-product .site-footer, .page-about .site-footer, .page-ack .site-footer { height: 244px; }
  .site-footer__in { left: var(--gutter); right: var(--gutter); width: auto; margin: 0; }
  .site-footer__rule { top: 86px; width: 100%; height: 4px; }
  .site-footer__tulip, .site-footer--home .site-footer__tulip { left: 50%; width: 120px; margin-left: -60px; top: 14px; }
  .site-footer--home .site-footer__tulip { width: 132px; margin-left: -66px; top: 18px; }
  .site-footer__socials { left: auto; right: 0; top: 54px; gap: 14px; }
  .social svg { width: 22px; min-width: 0; }
  .site-footer__links, .site-footer--home .site-footer__links--l, .site-footer--home .site-footer__links--r {
    top: 104px; display: grid; grid-auto-flow: row; grid-template-columns: none; grid-auto-columns: auto; gap: 0; font-size: 14px;
  }
  .site-footer__links--l, .site-footer--home .site-footer__links--l { left: 0; text-align: left; }
  .site-footer__links--r, .site-footer--home .site-footer__links--r { left: auto; right: 0; text-align: right; }
  .site-footer__links--r > li { justify-content: flex-end; }
  .site-footer__link { padding: 8px 0; min-height: 32px; }
}

/* signup.css */
/* ---------- Sign-up form (footer + popup) ---------- */
.signup { position: relative; }
.signup__field { position: relative; display: block; }
.signup__input {
  width: 100%; height: 53px; border: 0; border-radius: var(--radius-input);
  background: var(--placeholder); color: var(--plum);
  padding: 0 60px 0 18px; font: 400 18px/1 var(--sans); letter-spacing: .02em;
  transition: box-shadow var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.signup__input::placeholder { color: rgba(72, 40, 75, .55); }
.signup__input:focus { outline: none; box-shadow: 0 0 0 2px var(--magenta); background: #e2e0e0; }
.signup__input[aria-invalid="true"] { box-shadow: 0 0 0 2px #c0392b; }
.signup__submit {
  position: absolute; right: 7px; top: 50%; width: 39px; height: 39px; margin-top: -19.5px;
  border-radius: 50%; border: 0; padding: 0; background: var(--plum); color: var(--cream);
  display: grid; place-items: center;
  transition: transform var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.signup__submit svg { width: 20px; height: 20px; transition: transform var(--t-fast) var(--ease); }
@media (hover: hover) {
  .signup__submit:hover { background: var(--magenta); }
  .signup__submit:hover svg { transform: translateX(2px); }
}
.signup__submit:active { transform: scale(.94); }
.signup__submit[disabled] { cursor: progress; }
.signup.is-loading .signup__submit svg { animation: kd-spin 900ms linear infinite; }
@keyframes kd-spin { to { transform: rotate(360deg); } }
.signup__hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.signup__msg { min-height: 0; margin-top: 10px; font-size: 15px; line-height: 1.45; }
.signup__msg:empty { display: none; }
.signup__msg.is-error { color: #ffb4a8; }
.signup__consent { margin-top: 10px; font-size: 13px !important; line-height: 1.5; opacity: .75; }
.signup__consent a { color: inherit; }
.signup.is-done .signup__field, .signup.is-done .signup__consent { display: none; }
.signup.is-done .signup__msg { margin-top: 0; font: 400 22px/1.3 var(--serif); }
.signup__note { display: block; margin-top: 6px; font: 13px/1.4 var(--sans); opacity: .75; }

/* light variant inside the popup */
.popup .signup__msg { color: var(--plum); }
.popup .signup__msg.is-error { color: #a1132e; }
.popup .signup__consent { display: none; } /* design shows the field only; consent line lives on the footer form */

/* ---------- Popup (<dialog>, 883 x 502 at desktop; variant A = bouquet, B = lilac) ---------- */
.popup {
  --pw: min(883px, calc(100vw - 32px));
  --p: calc(var(--pw) / 883);
  width: var(--pw); max-width: none; height: calc(502 * var(--p)); max-height: none;
  padding: 0; border: 0; border-radius: var(--radius-popup); overflow: hidden;
  background: var(--cream); color: var(--plum);
  box-shadow: 0 30px 80px -30px rgba(40, 18, 42, .55);
}
.popup::backdrop { background: rgba(72, 40, 75, .5); }
.popup__inner { position: relative; width: 100%; height: 100%; }
.popup__close {
  position: absolute; z-index: 3; top: 10px; right: 10px; width: 44px; height: 44px; border-radius: 50%;
  border: 0; background: rgba(242, 237, 223, .85); color: var(--plum); display: grid; place-items: center;
  transition: transform var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
.popup__close svg { width: 18px; height: 18px; }
.popup__close:hover { background: #e7dfcd; transform: rotate(90deg); }
.popup__title:focus { outline: none; }
.popup__title { position: absolute; z-index: 2; color: var(--plum); font-size: calc(52 * var(--p)); line-height: 1.1; white-space: nowrap; }
.popup .signup { position: absolute; z-index: 2; width: calc(452 * var(--p)); }
.popup .signup__input { height: calc(53 * var(--p)); }
.popup__art { position: absolute; z-index: 1; pointer-events: none; }
.popup__art img { width: 100%; height: auto; }

/* A: heading centred (ink top 79.5), field 200,138 452x53, bouquet 750.5x323 at 66,179 (clipped by the box) */
.popup--a .popup__title { left: 0; right: 0; text-align: center; top: calc(66 * var(--p)); }
.popup--a .signup { left: calc(200 * var(--p)); top: calc(138 * var(--p)); }
.popup--a .popup__art { left: calc(66 * var(--p)); top: calc(179 * var(--p)); width: calc(750.5 * var(--p)); }
.popup--a .signup__msg:not(:empty) { background: rgba(242, 237, 223, .92); border-radius: 6px; padding: 6px 10px; }
.popup .signup.is-done { text-align: center; } /* the thank-you sits centred under the centred heading */
@media (min-width: 641px) { .popup--a .signup.is-done { left: 60px; right: 60px; width: auto; } }

/* B: lilac 390x476 at 15,26; heading right-aligned, two lines ending at x 811; field 380,224 */
.popup--b .popup__title { right: calc(72 * var(--p)); top: calc(97 * var(--p)); text-align: right; font-size: calc(54 * var(--p)); line-height: .97; }
.popup--b .signup { left: calc(380 * var(--p)); top: calc(224 * var(--p)); }
.popup--b .popup__art { left: calc(15 * var(--p)); top: calc(26 * var(--p)); width: calc(390 * var(--p)); }

@media (max-width: 640px) {
  .popup { height: fit-content; max-height: calc(100svh - 32px); overflow-y: auto; }
  .popup__inner { display: flex; flex-direction: column; height: auto; padding: 56px 20px 0; }
  .popup .popup__title, .popup .signup, .popup .popup__art { position: relative; left: auto; right: auto; top: auto; width: auto; }
  .popup__title { font-size: clamp(25px, 7vw, 32px); white-space: normal; text-align: center; }
  .popup .signup { margin-top: 18px; }
  .popup .signup__input { height: 46px; font-size: 15px; }
  .popup--a .popup__art { width: calc(100% + 40px); margin: 8px -20px 0; } /* no negative margin: it made the popup scroll by 8 px */
  .popup--b .popup__inner { padding-bottom: 0; }
  .popup--b .popup__title { order: 0; text-align: center; font-size: clamp(25px, 7vw, 32px); }
  .popup--b .signup { order: 1; }
  .popup--b .popup__art { order: 2; width: 62%; margin: 12px auto -40px 0; }
}
@media (prefers-reduced-motion: no-preference) {
  .popup[open] { animation: popup-in 420ms var(--ease); }
  .popup[open]::backdrop { animation: fade-in 420ms var(--ease); }
  @keyframes popup-in { from { opacity: 0; transform: translateY(18px) scale(.98); } to { opacity: 1; transform: none; } }
  @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
}

/* misc.css */
/* ---------- Simple pages: 404 and "coming soon" ---------- */
.simple {
  min-height: 72svh; display: grid; place-content: center; text-align: center; gap: 20px;
  padding: 140px var(--gutter) 120px; position: relative; overflow: hidden;
}
.simple__title { font-size: clamp(38px, 7vw, 92px); }
.simple__text { font-size: clamp(15px, 1.6vw, 20px); max-width: 36ch; margin-inline: auto; }
.simple__link { justify-self: center; margin-top: 8px; width: auto; padding: 0 26px; }

/* ---------- Scroll reveals (only when JS runs and motion is welcome) ---------- */
@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity var(--t-med) var(--ease), transform var(--t-med) var(--ease); }
  .js [data-reveal].is-in { opacity: 1; transform: none; }
  .js [data-reveal-delay="1"] { transition-delay: 90ms; }
  .js [data-reveal-delay="2"] { transition-delay: 180ms; }
  .js [data-reveal-delay="3"] { transition-delay: 270ms; }
}

/* ---------- Reduced motion: no transitions or animations anywhere (video + sway are stopped in JS) ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }
}

/* ---------- Contact (v4 "Get in Touch" frame: heading ink (104, 214), intro from 297; form at x 647, 654 wide,
   labels from 222; flower = the v3 2x layer export, 528.5 x 566 at (0, 159), its bottom = the frame bottom 725) ---------- */
.contact {
  position: relative; max-width: 1440px; min-height: calc(725 * var(--u)); margin-inline: auto;
  display: grid; grid-template-columns: calc(420 * var(--u)) minmax(0, calc(654 * var(--u))); column-gap: calc(125 * var(--u)); align-content: start;
  padding: calc(209 * var(--u)) calc(139 * var(--u)) calc(60 * var(--u)) calc(102 * var(--u));
}
.contact__flower {
  position: absolute; z-index: 0; left: min(0px, (1440px - 100cqw) / 2); bottom: 0; width: calc(528.5 * var(--u)); pointer-events: none;
  -webkit-mask-image: linear-gradient(#000 82%, transparent); mask-image: linear-gradient(#000 82%, transparent);
}
.contact__flower img { width: 100%; height: auto; }
.contact__text, .cform { position: relative; z-index: 1; }
.contact__title { font-size: calc(67 * var(--ut)); line-height: 1; letter-spacing: -.01em; }
.contact__intro { max-width: calc(398 * var(--u)); margin-top: calc(22 * var(--u)); font-size: max(14px, calc(15 * var(--ut))); line-height: 1.6; }
.contact__email { margin-top: 18px; font: 400 max(18px, calc(24 * var(--ut))) / 1.2 var(--serif); }
.contact__email a { color: var(--magenta); }
.cform { display: grid; row-gap: 22px; align-content: start; padding-top: 8px; }
.cform__row { display: grid; grid-template-columns: 1fr 1fr; column-gap: 20px; }
.cform__field { display: grid; row-gap: 6px; }
.cform__label { font-size: 12.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--plum); padding: 0; }
.cform__input {
  width: 100%; height: 46px; border: 0; border-bottom: 1px solid rgba(72, 40, 75, .45); border-radius: 0; background: transparent;
  padding: 0 2px; color: var(--plum); font: 500 16px/1.4 var(--sans);
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.cform__textarea { height: auto; min-height: 140px; padding-top: 10px; resize: vertical; border: 1px solid rgba(72, 40, 75, .3); border-radius: 6px; padding: 10px 12px; }
.cform__input:focus { outline: none; border-color: var(--magenta); box-shadow: 0 1px 0 var(--magenta); }
.cform__textarea:focus { box-shadow: 0 0 0 1px var(--magenta); }
.cform__input[aria-invalid="true"] { border-color: #c0392b; }
.cform__types { border: 0; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.cform__types legend { margin-bottom: 8px; }
.cform__chip { position: relative; }
.cform__chip input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.cform__chip span { display: block; padding: 7px 14px; border: 1px solid rgba(72, 40, 75, .35); border-radius: 999px; font-size: 14px; transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease); }
.cform__chip input:checked + span { background: var(--plum); border-color: var(--plum); color: var(--cream); }
.cform__chip input:focus-visible + span { outline: 2px solid var(--magenta); outline-offset: 2px; }
@media (hover: hover) { .cform__chip:hover span { border-color: var(--plum); } }
.cform__hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.cform__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }
.cform__send { width: auto; padding: 0 24px; }
.cform__msg { font-size: 15px; line-height: 1.45; }
.cform__msg:empty { display: none; }
.cform__msg.is-error { color: #a1132e; }
.cform__note { display: block; margin-top: 4px; font-size: 13px; opacity: .75; }
.cform.is-done > :not(.cform__foot), .cform.is-done .cform__send { display: none; }
.cform.is-done .cform__msg { font: 400 26px/1.3 var(--serif); }
.cform__msg:focus { outline: none; }

/* ---------- Image acknowledgements (v4 frame, 1440 x 2627): carnation = her 2x layer export, 583 x 898 at (0, 104),
   cut by the screen's left edge; heading 36 px design, ink (374, 229); intro 20 px design from ink top 306, x 375, 973
   wide; the credits run on in small type (11 px design, here 12 px at least, so they stay readable);
   "While you're browsing..." ink (102, 1887), cards 345 x 254 from (126, 1954); footer at 2369. With a long credits
   list the page simply grows. ---------- */
.ack { position: relative; max-width: 1440px; margin-inline: auto; min-height: calc(1891 * var(--u)); padding: calc(222 * var(--u)) calc(92 * var(--u)) calc(60 * var(--u)) calc(375 * var(--u)); }
.ack__flower { position: absolute; z-index: 0; left: min(0px, (1440px - 100cqw) / 2); top: calc(104 * var(--u)); width: calc(583 * var(--u)); pointer-events: none; }
.ack__flower img { width: 100%; height: auto; }
.ack__text { position: relative; z-index: 1; max-width: calc(973 * var(--u)); color: rgba(51, 16, 55, .9); }
.ack__title { font-size: calc(48.25 * var(--ut)); line-height: 1.2; letter-spacing: -.01em; color: inherit; }
.ack__intro { margin-top: calc(26 * var(--u)); font: 400 max(15px, calc(20.1 * var(--ut))) / 1.53 var(--sans); }
.ack__credits { list-style: none; margin: calc(14 * var(--u)) 0 0; padding: 0; font: 400 max(12px, calc(11 * var(--u))) / 1.53 var(--sans); }
.ack__credit { display: inline; }
.ack__credit a { color: inherit; }
.browse--ack { max-width: 1440px; margin-inline: auto; padding: 0 0 calc(127.7 * var(--u)) calc(126 * var(--u)); }
.browse--ack .browse__title { margin: calc(-8 * var(--u)) 0 0 calc(-24 * var(--u)); }
.browse--ack .browse__grid { margin-top: calc(26 * var(--u)); }
.product__links { margin-top: 14px; font-size: 14px; letter-spacing: .04em; }
.product__links a { color: var(--magenta); }

@media (max-width: 760px) {
  .contact { grid-template-columns: minmax(0, 1fr); row-gap: 28px; min-height: 0; padding: 84px var(--gutter) 72px; }
  .contact__flower { position: relative; order: 1; left: auto; bottom: auto; width: 56vw; margin: calc(-28px - 20.4vw) 0 -36px calc(-1 * var(--gutter)); } /* its top 34% is empty */
  .contact__text { order: 0; } .cform { order: 2; }
  .contact__title { font-size: 40px; }
  .contact__intro { max-width: none; margin-top: 14px; font-size: 14.5px; }
  .cform__row { grid-template-columns: minmax(0, 1fr); row-gap: 22px; }
  .cform.is-done .cform__msg { font-size: 22px; }
  .ack { min-height: 0; padding: 92px var(--gutter) 40px calc(var(--gutter) + 30vw); }
  .ack__flower { width: 34vw; top: 70px; }
  .ack__title { font-size: 30px; }
  .ack__intro { margin-top: 12px; font-size: 15px; }
  .ack__credits { margin-top: 10px; font-size: 12.5px; }
  .browse--ack { padding: 24px var(--gutter) 64px; }
  .browse--ack .browse__title { margin-left: 0; }
}
