/* ============================================================
   Kenki — HOME (2026 rebuild)

   An editorial, full-bleed layout that owns the homepage only.
   `styles.css` stays the shared system (tokens, nav, footer,
   buttons, legal pages); everything here is prefixed `k-` so it
   cannot collide with it.

   Motion personality: PHYSICAL. Three curves only, inherited from
   styles.css: --spring-snappy (arrivals), --spring-smooth (state),
   --ease-snap (hover).
   ============================================================ */

/* ---- home-only scale ------------------------------------- */
.k-sec { padding-block: clamp(96px, 14vh, 190px); }
.k-sec-head { max-width: min(100%, 760px); margin-bottom: clamp(40px, 6vw, 72px); }
.k-sec-head h2 { font-size: clamp(2.4rem, 5.4vw, 4.6rem); line-height: 0.98; letter-spacing: -0.035em; max-width: 15ch; margin: 0; }
.k-sec-head h2 .accent { font-style: italic; }
.k-sec-head-split {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: clamp(24px, 5vw, 72px);
  align-items: end;
  max-width: none;
}
.k-sec-head-split .k-lede { padding-bottom: 0.5em; }
@media (max-width: 860px) {
  .k-sec-head-split { grid-template-columns: 1fr; align-items: start; }
  .k-sec-head { max-width: none; }
}

.k-lede {
  font-size: clamp(1.05rem, 1.35vw, 1.24rem);
  line-height: 1.55;
  color: var(--text-dim);
  max-width: 46ch;
}
.k-eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 18px;
}
.k-eyebrow em { font-style: normal; }
.k-eyebrow::before {
  content: "";
  width: 34px;
  height: 1px;
  background: var(--sage);
  flex: none;
  transform-origin: left;
}
.k-num {
  display: block;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  color: var(--tan);
  margin-bottom: 14px;
}

/* Shared device frame ---------------------------------------
   Reads as a current iPhone (16 Pro proportions): a 1%-wide
   titanium rim, an even 2.4% black bezel, a 393:852 screen with a
   real corner radius (55pt), a Dynamic Island, a drawn status bar
   (9:41, signal, wifi, battery) and the four side buttons.

   All geometry is a percentage of the FRAME'S OWN width, so a
   170px gallery phone and a 300px hero phone are the same object.
   (The old frame used padding-%, which resolves against the PARENT
   width - that is why the screenshots sat off-centre in the hero.)

   Layers, bottom to top:
     figure          rim (metal gradient) + drop shadow
     figure > i      side buttons (drawn outside the rim)
     figure::before  bezel; its content box is the screen ground
                     and carries the status bar artwork
     figure > img    the capture, below the status bar
     figure::after   Dynamic Island

   Screen maths (W = frame width): rim 1%, bezel 2.4% -> screen
   93.2% wide = 393pt, so 1pt = 0.2371% W. Screen height 852pt =
   202.06% W, status bar 53.4pt = 12.66% W, capture 798.6pt =
   189.4% W. Frame height = 202.06 + 2*3.4 = 208.8% W. */
.k-dev {
  --rim: linear-gradient(155deg, #ece9e2 0%, #c9c5bd 16%, #8f8c85 38%, #d9d5cd 55%, #86837c 76%, #cbc7bf 100%);
  --btn: linear-gradient(90deg, #7c7972, #c2beb6 45%, #8b8881);
  --sb: var(--screen-bg);
  --sb-art: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 393 54'%3E%3Ctext x='56' y='34.5' text-anchor='middle' font-family='-apple-system,BlinkMacSystemFont,Inter,Roboto,Helvetica,Arial,sans-serif' font-size='17' font-weight='600' letter-spacing='-0.3' fill='%231A1713'%3E9:41%3C/text%3E%3Cg fill='%231A1713'%3E%3Crect x='292' y='28.5' width='3.2' height='4' rx='1'/%3E%3Crect x='297.2' y='26' width='3.2' height='6.5' rx='1'/%3E%3Crect x='302.4' y='23.5' width='3.2' height='9' rx='1'/%3E%3Crect x='307.6' y='20.5' width='3.2' height='12' rx='1'/%3E%3C/g%3E%3Cg fill='none' stroke='%231A1713' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M322 25.6a15 15 0 0 1 21 0'/%3E%3Cpath d='M326.3 29.6a9 9 0 0 1 12.4 0'/%3E%3C/g%3E%3Ccircle cx='332.5' cy='33.2' r='1.9' fill='%231A1713'/%3E%3Crect x='348' y='20.5' width='26' height='12.5' rx='4' fill='none' stroke='%231A1713' stroke-opacity='.38' stroke-width='1.2'/%3E%3Crect x='350.2' y='22.7' width='21.6' height='8.1' rx='2.2' fill='%231A1713'/%3E%3Cpath d='M375.6 24.4v4.7a2.4 2.4 0 0 0 0-4.7z' fill='%231A1713' fill-opacity='.4'/%3E%3C/svg%3E");
  position: relative;
  display: block;
  margin: 0;
  aspect-ratio: 1000 / 2088;
  border-radius: 16.1% / 7.71%;
  background: var(--rim);
  box-shadow:
    0 0 0 0.5px rgba(0, 0, 0, 0.35),
    0 1px 2px rgba(0, 0, 0, 0.25),
    0 18px 30px -16px rgba(26, 23, 19, 0.45),
    0 60px 90px -36px rgba(26, 23, 19, 0.5);
}
.k-dev-dim { --sb: #bfbab4; }
/* Bezel + screen ground + status bar */
.k-dev::before {
  content: "";
  position: absolute;
  inset: 0.479% 1%;
  padding: 2.4%;
  box-sizing: border-box;
  border-radius: 15.41% / 7.3%;
  background:
    var(--sb-art) top center / 100% auto no-repeat content-box,
    linear-gradient(var(--sb), var(--sb)) content-box,
    #0a0a0b padding-box;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.045);
}
/* Side buttons: action, volume up, volume down (left); power (right). */
.k-dev > i {
  position: absolute;
  inset: 0 -1.1%;
  pointer-events: none;
  background:
    var(--btn) 0 18.04% / 1.08% 3% no-repeat,
    var(--btn) 0 25% / 1.08% 6% no-repeat,
    var(--btn) 0 33% / 1.08% 6% no-repeat,
    var(--btn) 100% 27.6% / 1.08% 9.5% no-repeat;
}
.k-dev img {
  position: absolute;
  z-index: 1;
  left: 3.4%;
  top: 7.69%;
  width: 93.2%;
  height: auto;
  aspect-ratio: 620 / 1260;
  border-radius: 0 0 13.63% 13.63% / 0 0 6.7% 6.7%;
  display: block;
}
/* Dynamic Island, with the camera glint on its right end. */
.k-dev::after {
  content: "";
  position: absolute;
  top: 2.88%;
  left: 50%;
  width: 29.9%;
  aspect-ratio: 126 / 37;
  transform: translateX(-50%);
  border-radius: 999px;
  background: radial-gradient(circle at 80% 50%, #1b2431 0, #0d1219 9%, #050607 13%);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.035);
  z-index: 2;
}

:root { --screen-bg: #F6F1EA; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --screen-bg: #110F0D; }
  :root:not([data-theme="light"]) .k-dev {
    --rim: linear-gradient(155deg, #57554f 0%, #2f2e2b 18%, #1b1a18 40%, #4a4844 56%, #181715 78%, #3d3b37 100%);
    --btn: linear-gradient(90deg, #232220, #4d4b46 45%, #2a2926);
    --sb-art: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 393 54'%3E%3Ctext x='56' y='34.5' text-anchor='middle' font-family='-apple-system,BlinkMacSystemFont,Inter,Roboto,Helvetica,Arial,sans-serif' font-size='17' font-weight='600' letter-spacing='-0.3' fill='%23F6F1E8'%3E9:41%3C/text%3E%3Cg fill='%23F6F1E8'%3E%3Crect x='292' y='28.5' width='3.2' height='4' rx='1'/%3E%3Crect x='297.2' y='26' width='3.2' height='6.5' rx='1'/%3E%3Crect x='302.4' y='23.5' width='3.2' height='9' rx='1'/%3E%3Crect x='307.6' y='20.5' width='3.2' height='12' rx='1'/%3E%3C/g%3E%3Cg fill='none' stroke='%23F6F1E8' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M322 25.6a15 15 0 0 1 21 0'/%3E%3Cpath d='M326.3 29.6a9 9 0 0 1 12.4 0'/%3E%3C/g%3E%3Ccircle cx='332.5' cy='33.2' r='1.9' fill='%23F6F1E8'/%3E%3Crect x='348' y='20.5' width='26' height='12.5' rx='4' fill='none' stroke='%23F6F1E8' stroke-opacity='.38' stroke-width='1.2'/%3E%3Crect x='350.2' y='22.7' width='21.6' height='8.1' rx='2.2' fill='%23F6F1E8'/%3E%3Cpath d='M375.6 24.4v4.7a2.4 2.4 0 0 0 0-4.7z' fill='%23F6F1E8' fill-opacity='.4'/%3E%3C/svg%3E");
    box-shadow: 0 0 0 0.5px rgba(0,0,0,0.6), 0 1px 2px rgba(0,0,0,0.5), 0 18px 30px -16px rgba(0,0,0,0.6), 0 60px 90px -36px rgba(0,0,0,0.75);
  }
  :root:not([data-theme="light"]) .k-dev-dim { --sb: #0c0b09; }
}
:root[data-theme="dark"] { --screen-bg: #110F0D; }
:root[data-theme="dark"] .k-dev {
  --rim: linear-gradient(155deg, #57554f 0%, #2f2e2b 18%, #1b1a18 40%, #4a4844 56%, #181715 78%, #3d3b37 100%);
  --btn: linear-gradient(90deg, #232220, #4d4b46 45%, #2a2926);
  --sb-art: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 393 54'%3E%3Ctext x='56' y='34.5' text-anchor='middle' font-family='-apple-system,BlinkMacSystemFont,Inter,Roboto,Helvetica,Arial,sans-serif' font-size='17' font-weight='600' letter-spacing='-0.3' fill='%23F6F1E8'%3E9:41%3C/text%3E%3Cg fill='%23F6F1E8'%3E%3Crect x='292' y='28.5' width='3.2' height='4' rx='1'/%3E%3Crect x='297.2' y='26' width='3.2' height='6.5' rx='1'/%3E%3Crect x='302.4' y='23.5' width='3.2' height='9' rx='1'/%3E%3Crect x='307.6' y='20.5' width='3.2' height='12' rx='1'/%3E%3C/g%3E%3Cg fill='none' stroke='%23F6F1E8' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M322 25.6a15 15 0 0 1 21 0'/%3E%3Cpath d='M326.3 29.6a9 9 0 0 1 12.4 0'/%3E%3C/g%3E%3Ccircle cx='332.5' cy='33.2' r='1.9' fill='%23F6F1E8'/%3E%3Crect x='348' y='20.5' width='26' height='12.5' rx='4' fill='none' stroke='%23F6F1E8' stroke-opacity='.38' stroke-width='1.2'/%3E%3Crect x='350.2' y='22.7' width='21.6' height='8.1' rx='2.2' fill='%23F6F1E8'/%3E%3Cpath d='M375.6 24.4v4.7a2.4 2.4 0 0 0 0-4.7z' fill='%23F6F1E8' fill-opacity='.4'/%3E%3C/svg%3E");
  box-shadow: 0 0 0 0.5px rgba(0,0,0,0.6), 0 1px 2px rgba(0,0,0,0.5), 0 18px 30px -16px rgba(0,0,0,0.6), 0 60px 90px -36px rgba(0,0,0,0.75);
}
:root[data-theme="dark"] .k-dev-dim { --sb: #0c0b09; }

/* ============================================================
   01 · HERO
   ============================================================ */
.k-hero {
  position: relative;
  min-height: min(100svh, 980px);
  padding-block: clamp(24px, 6vh, 64px) 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  overflow: hidden;
  isolation: isolate;
}
.k-aura { position: absolute; inset: -20% -10% 0; z-index: -1; pointer-events: none; }
.k-aura i { position: absolute; display: block; border-radius: 50%; filter: blur(90px); }
.k-aura-a {
  width: 58vw; aspect-ratio: 1; left: 46%; top: -18%;
  background: radial-gradient(circle, color-mix(in srgb, var(--sage) 38%, transparent), transparent 68%);
  animation: aura-a 22s ease-in-out infinite alternate;
}
.k-aura-b {
  width: 44vw; aspect-ratio: 1; left: -12%; top: 26%;
  background: radial-gradient(circle, var(--tan-wash), transparent 66%);
  animation: aura-b 28s ease-in-out infinite alternate;
}
@keyframes aura-a { to { transform: translate3d(-6%, 8%, 0) scale(1.12); } }
@keyframes aura-b { to { transform: translate3d(8%, -6%, 0) scale(1.08); } }

.k-hero-copy { position: relative; z-index: 2; }
.k-display {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: clamp(3.1rem, 10.4vw, 10.5rem);
  line-height: 0.9;
  letter-spacing: -0.045em;
  margin: 0;
  text-wrap: balance;
}
.k-display .accent { font-style: italic; }
.k-hero-foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: clamp(20px, 4vw, 56px);
  margin-top: clamp(28px, 4vw, 48px);
  padding-top: clamp(20px, 3vw, 34px);
  border-top: 1px solid var(--line);
}
.k-hero-cta { display: flex; gap: 12px; flex-wrap: wrap; }
@media (max-width: 780px) {
  .k-hero-foot { grid-template-columns: 1fr; align-items: start; }
}

/* The fanned devices. They bleed off the bottom on purpose - the
   hero is a stage, not a boxed two-column layout.

   Three transforms on three elements, so none fight over one
   property: .k-stage tilts toward the pointer (motion.js writes
   --rx/--ry), .k-slot fans out on scroll (view timeline), .k-dev
   rises in on load and then idles on a slow float. */
.k-hero { perspective: 1800px; }
.k-stage {
  position: relative;
  z-index: 1;
  margin-top: clamp(28px, 5vh, 64px);
  height: clamp(340px, 54vh, 600px);
  transform: rotateX(calc(var(--ry, 0) * -1deg)) rotateY(calc(var(--rx, 0) * 1deg));
  transition: transform 0.9s var(--spring-smooth);
  will-change: transform;
}
.k-slot {
  position: absolute;
  top: 0;
  left: 50%;
  width: clamp(190px, 21vw, 280px);
  margin-left: calc(clamp(190px, 21vw, 280px) / -2);
  transform-origin: 50% 100%;
}
.k-slot-c { z-index: 3; transform: translateY(-2%); }
.k-slot-l { z-index: 2; transform: translate(-72%, 5%) rotate(-11deg); }
.k-slot-r { z-index: 2; transform: translate(72%, 5%) rotate(11deg); }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .k-slot { animation: linear both; animation-timeline: view(); animation-range: entry 10% exit 90%; }
    .k-slot-c { animation-name: fan-c; }
    .k-slot-l { animation-name: fan-l; }
    .k-slot-r { animation-name: fan-r; }
    @keyframes fan-c { from { transform: translateY(6%) scale(0.97); } to { transform: translateY(-14%) scale(1); } }
    @keyframes fan-l { from { transform: translate(-52%, 12%) rotate(-6deg); } to { transform: translate(-86%, -4%) rotate(-15deg); } }
    @keyframes fan-r { from { transform: translate(52%, 12%) rotate(6deg); } to { transform: translate(86%, -4%) rotate(15deg); } }
  }
}
/* Load: rise from below on the arrival spring, then float. Hidden
   state only under .js-motion so a JS failure still shows phones. */
.js-motion .k-stage .k-dev {
  animation:
    k-rise 1.25s var(--spring-snappy) both,
    k-float 7s ease-in-out infinite 1.25s;
}
.js-motion .k-slot-l .k-dev { animation-delay: 380ms, 1.63s; }
.js-motion .k-slot-c .k-dev { animation-delay: 260ms, 1.51s; --float: -1.8%; }
.js-motion .k-slot-r .k-dev { animation-delay: 500ms, 1.75s; animation-duration: 1.25s, 8s; }
@keyframes k-rise {
  from { opacity: 0; transform: translateY(14%) scale(0.96); filter: blur(6px); }
  to   { opacity: 1; transform: translateY(0) scale(1); filter: none; }
}
@keyframes k-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(var(--float, -1.3%)); }
}

@media (max-width: 760px) {
  .k-stage { height: 270px; }
  .k-slot { width: 176px; margin-left: -88px; }
  .k-slot-l { transform: translate(-58%, 8%) rotate(-10deg) scale(0.86); }
  .k-slot-r { transform: translate(58%, 8%) rotate(10deg) scale(0.86); }
}
/* On the narrowest screens the fan would run off both edges, so the
   stage drops to the single hero device. */
@media (max-width: 460px) {
  .k-stage { height: 250px; }
  .k-slot { width: 200px; margin-left: -100px; }
  .k-slot-l, .k-slot-r { display: none; }
}

/* ============================================================
   02 · RIBBON (marquee)
   ============================================================ */
.k-ribbon {
  overflow: hidden;
  background: var(--sage);
  color: var(--sage-ink);
  padding-block: 16px;
  border-block: 1px solid color-mix(in srgb, var(--bezel) 20%, transparent);
}
.k-ribbon-track { display: flex; width: max-content; animation: marquee 38s linear infinite; }
.k-ribbon:hover .k-ribbon-track { animation-play-state: paused; }
.k-ribbon-set { display: flex; align-items: center; gap: 26px; padding-right: 26px; white-space: nowrap; }
.k-ribbon-set b {
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.1rem, 1.9vw, 1.6rem);
  letter-spacing: -0.02em;
}
.k-ribbon-set i {
  font-style: normal;
  font-family: var(--f-mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.72;
}
.k-ribbon-set i::after { content: "\2022"; margin-left: 26px; opacity: 0.5; }
@keyframes marquee { to { transform: translateX(-50%); } }

/* ============================================================
   03 · MANIFESTO
   ============================================================ */
.k-manifesto { padding-block: clamp(96px, 16vh, 210px); }
.k-manifesto-text {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(1.7rem, 4.4vw, 3.6rem);
  line-height: 1.16;
  letter-spacing: -0.03em;
  max-width: 22ch;
  color: var(--text);
}
/* Words light up one by one as the block scrolls through the
   viewport. The base colour is the LIT one, so if scroll-driven
   animation is unavailable the sentence simply reads normally. */
.k-manifesto-text .w > i { color: var(--text); }
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .k-manifesto-text .w > i {
      animation: word-lit linear both;
      animation-timeline: view();
      animation-range: entry 30% cover calc(42% + var(--i, 0) * 2.2%);
    }
    @keyframes word-lit {
      from { color: color-mix(in srgb, var(--text) 24%, transparent); }
      to { color: var(--text); }
    }
  }
}

/* ============================================================
   04 · THE THREE MOVES (sticky media, scrolling chapters)
   ============================================================ */
.k-stack { padding-block: clamp(40px, 6vh, 80px) clamp(80px, 12vh, 150px); }
.k-stack-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(32px, 6vw, 100px);
  align-items: start;
}
.k-stack-media { position: sticky; top: calc(var(--nav-h) + 40px); }
.k-stack-frame { display: grid; width: min(300px, 78%); margin-inline: auto; }
.k-stack-frame .k-shot {
  grid-area: 1 / 1;
  width: 100%;
  opacity: 0;
  transform: translateY(22px) scale(0.96) rotateY(-9deg);
  filter: blur(4px);
  transition:
    opacity 0.55s var(--spring-snappy),
    transform 0.8s var(--spring-snappy),
    filter 0.55s var(--spring-snappy);
}
.k-stack-frame { perspective: 1400px; }
.k-stack-frame .k-shot.is-live { opacity: 1; transform: none; filter: none; }
.k-stack-dots { display: flex; gap: 8px; justify-content: center; margin-top: 26px; }
.k-stack-dots span {
  width: 26px; height: 3px; border-radius: 999px;
  background: var(--line-strong);
  transition: background-color 0.4s var(--ease-snap), transform 0.4s var(--spring-smooth);
}
.k-stack-dots span.is-live { background: var(--sage); transform: scaleX(1.35); }

/* Short windows: size the pinned device off the viewport height so the
   frame and its dots always fit, instead of being cut by the fold. */
@media (min-width: 1001px) and (max-height: 860px) {
  .k-stack .k-stack-media { top: calc(var(--nav-h) + 20px); }
  .k-stack .k-stack-frame { width: min(30vh, 300px); }
  .k-stack .k-stack-dots { margin-top: 18px; }
}

.k-chapter { padding-block: clamp(48px, 12vh, 130px); }
/* Desktop keeps the shared sticky device; the per-chapter copy only
   appears once that column is gone. */
.k-chapter-shot { display: none; }
.k-chapter:first-child { padding-top: clamp(8px, 3vh, 32px); }
.k-chapter h2 {
  font-size: clamp(2.1rem, 4.2vw, 3.5rem);
  line-height: 1.0;
  letter-spacing: -0.035em;
  margin: 0 0 20px;
  max-width: 15ch;
}
.k-chapter .k-eyebrow { justify-content: flex-start; }
.k-chapter .k-eyebrow .tag { margin-right: 4px; }
.k-list { list-style: none; padding: 0; margin: 32px 0 0; display: grid; gap: 0; }
.k-list li {
  display: grid;
  gap: 4px;
  padding: 18px 0;
  border-top: 1px solid var(--line);
}
.k-list li:last-child { border-bottom: 1px solid var(--line); }
.k-list b { font-weight: 600; font-size: 15.5px; }
.k-list span { font-size: 14.5px; color: var(--text-dim); max-width: 52ch; }

@media (max-width: 1000px) {
  .k-stack-grid { grid-template-columns: 1fr; }
  /* No room for a pinned column beside the copy, so the shared media
     column goes away and every chapter shows its own screen inline.
     Nothing depends on the scroll position any more. */
  .k-stack-media { display: none; }
  .k-chapter { padding-block: clamp(40px, 7vh, 72px); }
  .k-chapter-shot {
    display: block;
    width: min(250px, 58%);
    margin: 0 auto clamp(26px, 4vw, 40px);
  }
  .k-chapter h2 { max-width: 18ch; }
}

/* ============================================================
   05 · GALLERY (pinned horizontal run)
   ============================================================ */
.k-gal { background: var(--bg-1); border-block: 1px solid var(--line); }
.k-gal-pin { padding-block: clamp(48px, 8vh, 96px) clamp(20px, 3vh, 40px); }
.k-gal-head { margin-bottom: 30px; }
.k-gal-scroll { overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch; }
.k-gal-scroll::-webkit-scrollbar { height: 0; }
.k-gal-track {
  display: flex;
  gap: clamp(20px, 3vw, 42px);
  /* The scroller clips its overflow, so the devices' drop shadows
     need padding to live in — otherwise they end on a hard line. */
  padding: 26px clamp(20px, 4vw, 44px) 76px;
  width: max-content;
}
.k-gal-item {
  margin: 0;
  scroll-snap-align: center;
  width: clamp(180px, 21vw, 244px);
  flex: none;
  display: flex;
  flex-direction: column;
}
.k-gal-item .k-dev { width: 100%; transition: transform 0.6s var(--spring-smooth); }
.k-gal-item:hover .k-dev { transform: translateY(-10px); }
.k-gal-item figcaption {
  margin-top: 18px;
  /* Two-line captions must not push their neighbours out of line. */
  min-height: 2.6em;
  font-family: var(--f-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-faint);
  text-align: center;
}

/* Where scroll-driven animation exists, pin the strip and run it
   horizontally as the section scrolls. Elsewhere it stays a plain
   swipeable strip, which is the correct mobile behaviour anyway. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) and (min-width: 901px) {
    /* The section owns a named view-timeline; the strip inside the
       sticky pin reads it. `contain` covers exactly the window in
       which the section fills the viewport — i.e. while it is
       pinned — so the horizontal run starts and ends with the pin. */
    .k-gal { height: 230vh; view-timeline: --gal block; }
    .k-gal-pin { position: sticky; top: 0; height: 100svh; display: flex; flex-direction: column; justify-content: center; }
    .k-gal-scroll { overflow: hidden; }
    .k-gal-track {
      animation: gal-run linear both;
      animation-timeline: --gal;
      animation-range: contain 0% contain 100%;
    }
    @keyframes gal-run { from { transform: translateX(3vw); } to { transform: translateX(calc(-100% + 94vw)); } }
  }
}

/* ============================================================
   06 · BENTO
   ============================================================ */
.k-bento {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 22px);
}
.k-cell {
  grid-column: span 3;
  position: relative;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: clamp(26px, 3vw, 40px);
  transition:
    transform 0.5s var(--ease-snap),
    border-color 0.35s var(--ease-snap),
    box-shadow 0.5s var(--ease-snap);
}
.k-cell:hover {
  transform: translateY(-6px);
  border-color: color-mix(in srgb, var(--sage) 50%, var(--line-strong));
  box-shadow: var(--shadow-float);
}
.k-cell h3 {
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.35rem, 2.1vw, 1.85rem);
  line-height: 1.08;
  letter-spacing: -0.025em;
  margin: 0 0 12px;
  max-width: 16ch;
}
.k-cell h3 .accent { font-style: italic; }
.k-cell p { font-size: 14.5px; color: var(--text-dim); max-width: 42ch; }
.k-cell .k-eyebrow { margin-bottom: 14px; }

.k-cell-wide {
  grid-column: span 6;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: clamp(24px, 4vw, 64px);
  align-items: end;
  padding-bottom: 0;
}
.k-cell-wide .k-cell-copy { padding-bottom: clamp(26px, 3vw, 40px); }
/* The device bleeds past the card edge on purpose — cropped by the
   card's own radius, not by an accident of height. */
.k-cell-wide .k-cell-shot { width: clamp(190px, 21vw, 262px); margin-bottom: -14%; }
.k-cell:not(.k-cell-wide) .k-cell-shot {
  display: block;
  width: 70%;
  margin: 28px auto -24%;
}
.k-cell-flat { grid-column: span 3; background: var(--surface-2); }
.k-cell-flat .tag { margin-bottom: 14px; }
.k-cell-shot { transition: transform 0.6s var(--spring-smooth); }
.k-cell:hover .k-cell-shot { transform: translateY(-10px); }

.k-ticks { list-style: none; padding: 0; margin: 18px 0 0; display: grid; gap: 10px; font-size: 14.5px; color: var(--text-dim); }
.k-ticks li { position: relative; padding-left: 24px; }
.k-ticks li::before {
  content: "";
  position: absolute; left: 1px; top: 7px;
  width: 10px; height: 6px;
  border-left: 2px solid var(--sage);
  border-bottom: 2px solid var(--sage);
  transform: rotate(-45deg);
}

@media (max-width: 900px) {
  .k-bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .k-cell, .k-cell-flat { grid-column: span 1; }
  .k-cell-wide { grid-column: span 2; grid-template-columns: 1fr; }
  .k-cell-wide .k-cell-shot { width: min(220px, 60%); margin-inline: auto; }
}
@media (max-width: 620px) {
  .k-bento { grid-template-columns: 1fr; }
  .k-cell, .k-cell-flat, .k-cell-wide { grid-column: span 1; }
  .k-cell:not(.k-cell-wide) .k-cell-shot { width: 62%; margin-bottom: -18%; }
}

/* ============================================================
   07 · STEPS
   ============================================================ */
.k-step-list { list-style: none; padding: 0; margin: 0; }
.k-step-list li {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: clamp(16px, 4vw, 60px);
  align-items: baseline;
  padding-block: clamp(28px, 4vw, 46px);
  border-top: 1px solid var(--line);
}
.k-step-list li:last-child { border-bottom: 1px solid var(--line); }
.k-step-list .k-num { font-size: clamp(1.6rem, 3.4vw, 2.6rem); font-family: var(--f-display); letter-spacing: -0.02em; color: var(--tan); margin: 0; }
.k-step-list h3 {
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.5rem, 2.8vw, 2.2rem);
  letter-spacing: -0.028em;
  line-height: 1.06;
  margin: 0 0 10px;
}
.k-step-list p { color: var(--text-dim); max-width: 52ch; }
@media (max-width: 640px) { .k-step-list li { grid-template-columns: 1fr; gap: 8px; } }

/* ============================================================
   08 · PRIVACY
   ============================================================ */
.k-priv-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: clamp(18px, 2.5vw, 34px); }
.k-priv-item { position: relative; padding-top: 22px; border-top: 1px solid var(--line-strong); }
.k-priv-item::after {
  content: "";
  position: absolute; top: -1px; left: 0; right: 0; height: 1px;
  background: var(--sage);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.6s var(--ease-snap);
}
.k-priv-item:hover::after { transform: scaleX(1); }
.k-priv-item b { display: block; font-weight: 600; font-size: 15px; margin-bottom: 8px; }
.k-priv-item p { font-size: 13.5px; color: var(--text-dim); }
@media (max-width: 860px) { .k-priv-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .k-priv-grid { grid-template-columns: 1fr; } }

/* ============================================================
   09 · PRICING
   ============================================================ */
.k-plans { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(16px, 2vw, 26px); align-items: start; }
.k-plan {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  padding: clamp(28px, 3.2vw, 44px);
  display: flex;
  flex-direction: column;
  gap: 16px;
  transition: transform 0.5s var(--ease-snap), box-shadow 0.5s var(--ease-snap);
}
.k-plan:hover { transform: translateY(-5px); box-shadow: var(--shadow-float); }
.k-plan h3 { font-family: var(--f-display); font-weight: 600; font-size: 1.2rem; letter-spacing: -0.01em; margin: 0; }
.k-price { display: flex; align-items: baseline; gap: 8px; font-family: var(--f-display); }
.k-price strong { font-size: clamp(2.8rem, 5vw, 4rem); font-weight: 600; letter-spacing: -0.02em; line-height: 1; padding-left: 0.04em; font-variant-numeric: tabular-nums; }
.k-price span { font-family: var(--f-sans); font-size: 1rem; color: var(--text-dim); }
.k-price-sub { font-size: 13px; color: var(--text-faint); margin-top: -8px; }
.k-plan .btn { margin-top: auto; align-self: flex-start; }
.k-plan-hero {
  position: relative;
  background: linear-gradient(158deg, color-mix(in srgb, var(--sage) 13%, var(--surface)), var(--surface) 64%);
  border-color: color-mix(in srgb, var(--sage) 45%, var(--line));
  transform: translateY(-14px);
}
.k-plan-hero:hover { transform: translateY(-19px); }
.k-plan-pill {
  position: absolute; top: -13px; right: 26px;
  background: var(--sage); color: var(--sage-ink);
  font-family: var(--f-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  padding: 6px 12px; border-radius: 999px;
}
.k-price-note { margin-top: 26px; font-size: 12.5px; color: var(--text-faint); max-width: 62ch; }
@media (max-width: 760px) {
  .k-plans { grid-template-columns: 1fr; }
  .k-plan-hero, .k-plan-hero:hover { transform: none; }
}

/* ============================================================
   10 · FAQ
   ============================================================ */
.k-faq-sec .k-sec-head h2 { max-width: 18ch; }
.k-faq { border-top: 1px solid var(--line); }
.k-q { border-bottom: 1px solid var(--line); }
.k-q summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
  padding-block: clamp(22px, 2.6vw, 32px);
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(1.15rem, 2vw, 1.6rem);
  letter-spacing: -0.02em;
  transition: color 0.3s var(--ease-snap);
}
.k-q summary::-webkit-details-marker { display: none; }
.k-q summary:hover { color: var(--sage); }
.k-q summary i {
  position: relative;
  flex: none;
  width: 30px; height: 30px;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  transition: transform 0.5s var(--spring-smooth), border-color 0.3s var(--ease-snap), background-color 0.3s var(--ease-snap);
}
.k-q summary i::before, .k-q summary i::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  background: currentColor;
}
.k-q summary i::before { width: 11px; height: 1.5px; }
.k-q summary i::after { width: 1.5px; height: 11px; transition: transform 0.4s var(--spring-smooth); }
.k-q[open] summary i { transform: rotate(90deg); background: var(--sage-wash); border-color: var(--sage); color: var(--sage); }
.k-q[open] summary i::after { transform: scaleY(0); }
.k-a { padding: 0 60px 30px 0; color: var(--text-dim); font-size: 15.5px; max-width: 74ch; }
.k-a a { color: var(--sage); text-decoration: underline; text-underline-offset: 3px; }
.k-q[open] .k-a { animation: k-open 0.5s var(--spring-snappy) both; }
@keyframes k-open { from { opacity: 0; transform: translateY(-8px); } to { opacity: 1; transform: none; } }
@media (max-width: 560px) { .k-a { padding-right: 0; } }

/* ============================================================
   11 · GUIDES
   ============================================================ */
.k-guides { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(14px, 1.8vw, 22px); }
.k-guide {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 260px;
  padding: clamp(24px, 2.8vw, 36px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-xl);
  transition: transform 0.5s var(--ease-snap), border-color 0.35s var(--ease-snap), box-shadow 0.5s var(--ease-snap);
}
.k-guide:hover { transform: translateY(-6px); border-color: color-mix(in srgb, var(--sage) 50%, var(--line-strong)); box-shadow: var(--shadow-float); }
.k-guide h3 { font-family: var(--f-display); font-weight: 600; font-size: 1.28rem; line-height: 1.14; letter-spacing: -0.02em; margin: 0; }
.k-guide p { font-size: 14px; color: var(--text-dim); }
.k-more { margin-top: auto; padding-top: 14px; color: var(--sage); font-size: 14px; font-weight: 600; }
.k-more::after { content: " \2192"; display: inline-block; transition: transform 0.4s var(--spring-smooth); }
.k-guide:hover .k-more::after { transform: translateX(5px); }
@media (max-width: 860px) { .k-guides { grid-template-columns: 1fr; } }

/* ============================================================
   12 · CTA SLAB
   ============================================================ */
.k-cta {
  position: relative;
  overflow: hidden;
  background: var(--sage);
  color: var(--sage-ink);
  padding-block: clamp(80px, 13vh, 170px);
}
.k-cta::after {
  content: "";
  position: absolute; inset: auto -10% -60% 40%;
  aspect-ratio: 1;
  background: radial-gradient(circle, color-mix(in srgb, #ffffff 26%, transparent), transparent 62%);
  filter: blur(60px);
  pointer-events: none;
}
.k-cta-inner { position: relative; z-index: 1; }
.k-cta .k-eyebrow { color: color-mix(in srgb, var(--sage-ink) 62%, transparent); }
.k-cta .k-eyebrow::before { background: var(--sage-ink); opacity: 0.5; }
.k-cta-h {
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(2.7rem, 8vw, 7rem);
  line-height: 0.92;
  letter-spacing: -0.045em;
  margin: 0 0 22px;
  max-width: 14ch;
}
.k-cta-h .accent { color: color-mix(in srgb, var(--sage-ink) 78%, var(--sage)); font-style: italic; }
.k-cta p { color: color-mix(in srgb, var(--sage-ink) 78%, transparent); max-width: 50ch; margin-bottom: 34px; }
.k-cta .store-btn {
  background: var(--sage-ink);
  border-color: color-mix(in srgb, var(--sage-ink) 40%, transparent);
  color: var(--text);
}
.k-cta .store-btn svg { color: var(--text); }
.k-cta .store-btn .s-small { color: color-mix(in srgb, var(--text) 62%, transparent); }
.k-cta .store-btn:hover { transform: translateY(-3px); border-color: var(--sage-ink); }

/* ============================================================
   13 · MOTION — reveal system
   Hidden states only apply once motion.js has flagged the document,
   so a JS failure can never leave the page blank.
   ============================================================ */
.js-motion .k-rv,
.js-motion .k-in {
  opacity: 0;
  transform: translateY(26px);
  filter: blur(7px);
}
.js-motion .k-rv {
  transition:
    opacity 0.7s var(--spring-snappy),
    transform 0.85s var(--spring-snappy),
    filter 0.7s var(--spring-snappy);
  transition-delay: var(--d, 0ms);
}
.js-motion .k-rv.is-in { opacity: 1; transform: none; filter: none; }
.js-motion .k-in { animation: k-enter 0.9s var(--spring-snappy) both; animation-delay: var(--d, 0ms); }
.k-in-2 { --d: 180ms; }
.k-in-3 { --d: 300ms; }
@keyframes k-enter { to { opacity: 1; transform: none; filter: none; } }

/* Hero headline: word-by-word masked rise (built by motion.js). */
/* The clipping box has to be bigger than the glyph box: Fraunces
   descenders and the italic's overhang both spill past the line box,
   and `overflow: hidden` would slice them off. */
.k-display.split-word .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding: 0.06em 0.08em 0.26em;
  margin: -0.06em -0.08em -0.26em;
}
.k-display.split-word .w > i {
  display: inline-block;
  font-style: inherit;
  opacity: 1;
  transform: translateY(115%);
  animation: k-word 0.95s var(--spring-snappy) both;
  animation-delay: calc(var(--i, 0) * 60ms + 80ms);
}
@keyframes k-word { to { transform: none; } }

/* Manifesto words never hide — only their colour animates. */
.k-manifesto-text .w { display: inline-block; }

/* Scroll progress hairline */
.k-progress {
  position: fixed; inset: 0 0 auto 0; height: 2px; z-index: 60;
  pointer-events: none; transform-origin: left; transform: scaleX(0);
  background: linear-gradient(90deg, var(--sage), var(--tan), var(--peach));
  animation: k-progress linear both;
  animation-timeline: scroll(root block);
}
@keyframes k-progress { to { transform: scaleX(1); } }

@media (prefers-reduced-motion: reduce) {
  .js-motion .k-rv, .js-motion .k-in { opacity: 1; transform: none; filter: none; animation: none; transition: none; }
  .k-display.split-word .w > i { animation: none; transform: none; }
  .k-ribbon-track, .k-aura i, .k-stage .k-dev { animation: none; }
  .k-stage { transform: none; }
  .k-progress { display: none; }
  .k-manifesto-text .w > i { color: var(--text); }
}
@media (hover: none) {
  .k-cell:hover, .k-plan:hover, .k-guide:hover, .k-gal-item:hover .k-dev { transform: none; }
}

/* ============================================================
   14 · MOTION — pointer spotlight on cards
   motion.js writes --px/--py (0-1) on hover; the wash follows the
   cursor and fades in. Pure decoration, so it lives on a pseudo
   with the card's own radius and no layout impact.
   ============================================================ */
.k-cell, .k-plan, .k-guide { position: relative; }
.k-cell::before, .k-plan::before, .k-guide::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: 0;
  opacity: 0;
  background: radial-gradient(
    360px circle at calc(var(--px, 0.5) * 100%) calc(var(--py, 0.5) * 100%),
    color-mix(in srgb, var(--sage) 14%, transparent),
    transparent 60%);
  transition: opacity 0.5s var(--ease-snap);
}
.k-cell:hover::before, .k-plan:hover::before, .k-guide:hover::before { opacity: 1; }
.k-cell > *, .k-plan > *, .k-guide > * { position: relative; z-index: 1; }
.k-plan > .k-plan-pill { position: absolute; }
@media (hover: none) { .k-cell::before, .k-plan::before, .k-guide::before { display: none; } }

/* Fraunces' euro sign overhangs at display sizes; set it in the sans. */
.k-cur { font-family: var(--f-sans); font-weight: 500; font-size: 0.58em; vertical-align: 0.3em; margin-right: 0.04em; letter-spacing: 0; }
