/* ============================================================================
   FLOODLIT · Kimi — app shell
   ----------------------------------------------------------------------------
   This file is ADDITIVE. It never edits Kimi's markup; it occludes the board's
   annotation chrome and stages one screen at a time.

   Everything here draws on the BOARD's own custom properties (--ink, --flood,
   --hair2, --sheet-rgb, --dim-t …) so the shell re-themes with the palette
   switcher and never competes with the screen it frames.
   ============================================================================ */

:root {
  --k-bar-h: 58px;
  --k-top: 84px;
  --k-ease: cubic-bezier(.22, 1, .36, 1);
  --k-scale: 1;
}

/* ---------------------------------------------------------------- boot gate
   Nothing inside .wrap renders until the shell has staged a screen. This is not
   cosmetic: the board's IntersectionObservers drive the ignition animations, and
   an un-rendered subtree cannot intersect. Without this gate every screen's
   ignition is spent silently at load and you arrive to a still image. */
html[data-k]:not([data-k-ready]) .wrap > * { display: none; }

/* ------------------------------------------------------- occlude the board
   The board document is a design essay: header, carry-in, palette trial,
   ledger, footer. None of it is app. Hidden, not deleted — the board's own
   script still queries these nodes and would throw if they were gone. The
   shell marks every sibling off the path to the live screen. */
html[data-k] .k-hidden { display: none !important; }

/* per-screen annotation: captions, the numbered key, the callout pins, and
   board 05's photograph-slot notes — Kimi telling the reader that the drawn
   pitch stands in for a real photograph. All named classes, so hiding them
   involves no judgement about what is and is not part of the screen. */
html[data-k] .slot > .cap,
html[data-k] .slot > .key,
html[data-k] .slot > .why,
html[data-k] .why { display: none; }
/* not scoped to .phone — board 05 puts a photograph note inside the widescreen
   desk as well, and annotation is annotation wherever it is sitting */
html[data-k] .pin,
html[data-k] .ph-note { display: none; }

/* …restored on demand. This is Kimi's reasoning; worth reading, just not worth
   wearing while you look at the screen. */
html[data-k][data-k-notes="on"] .slot > .key { display: flex; }
html[data-k][data-k-notes="on"] .pin { display: flex; }
html[data-k][data-k-notes="on"] .ph-note { display: block; }

/* ---------------------------------------------------------------- the stage */
html[data-k] { scroll-behavior: auto; }
html[data-k] body { padding-bottom: 108px; }

/* Keep the board's own max-width and side padding. The desktop dossier has no
   width of its own — it fills this column, so widening it would stretch a
   surface Kimi drew at a fixed measure. Only the vertical rhythm changes. */
html[data-k] .wrap {
  padding-top: var(--k-top);
  padding-bottom: 0;
  min-height: 100vh;
  display: grid;
  /* Not centre: overflow alignment silently re-aligns an item wider than its
     track, which is what clipped the phone screen. `stretch` places a
     definitely-sized item (the 430px phone slot) at the start of the track so
     its position is knowable, while still letting the auto-width desktop
     dossier fill the column the board drew it in. The shell then centres by
     arithmetic in applyFit. `start` here would collapse the desk to its
     content width instead. */
  place-items: start stretch;
}

/* The board's sections carry essay-scale vertical rhythm. On a stage that
   shows one screen at a time it is dead height, and every pixel of it comes
   off the screen's scale. */
html[data-k] .wrap > section {
  padding-top: 0;
  padding-bottom: 0;
  margin-top: 0;
  margin-bottom: 0;
}

/* Boards 03 and 04 sit the phone beside its explanation in a two-column grid
   (460px 1fr). With the explanation occluded the phone would stay pinned to the
   left column instead of centring, so collapse both containers to a plain block
   and let the stage do the centring. */
html[data-k] .rail,
html[data-k] .split {
  display: block;
  overflow: visible;
  padding: 0;
  margin: 0;
  gap: 0;
  scroll-snap-type: none;
}

html[data-k] .slot.k-on,
html[data-k] .desk.k-on { display: block; }

html[data-k] .slot.k-on { width: 430px; }

/* the fit transform. JS sets --k-scale and cancels the leftover layout box
   with a negative margin, so a scaled screen leaves no dead scroll behind. */
html[data-k] .k-on {
  /* The horizontal offset is part of the transform, never a margin. A margin
     shrinks a stretched element (the desktop dossier fills its column), which
     makes it taller, which invalidates the scale computed from its height.
     A transform moves it without touching layout. */
  transform: translateX(var(--k-dx, 0px)) scale(var(--k-scale));
  transform-origin: top left;
}

html[data-k] .slot.k-on > .replay { margin-top: 18px; }

/* screen arrival — enter and exit along the same axis (§7 spatial consistency) */
@keyframes k-in-fwd  { from { opacity: 0; transform: translateX(calc(var(--k-dx, 0px) + 26px)) scale(var(--k-scale)); } }
@keyframes k-in-back { from { opacity: 0; transform: translateX(calc(var(--k-dx, 0px) - 26px)) scale(var(--k-scale)); } }
html[data-k] .k-on.k-enter-fwd  { animation: k-in-fwd .42s var(--k-ease) both; }
html[data-k] .k-on.k-enter-back { animation: k-in-back .42s var(--k-ease) both; }

/* ------------------------------------------------------------ wired taps
   A control the shell has given a destination. The board's own styling is
   untouched; this only says "this goes somewhere". */
html[data-k] [data-k-wired] { cursor: pointer; }
html[data-k] [data-k-wired]:active { filter: brightness(1.12); }
@media (hover: hover) {
  html[data-k] [data-k-wired]:hover { filter: brightness(1.08); }
}

/* ================================================================== chrome
   A translucent layer that floats over the work rather than boxing it in.
   Content scrolls underneath; the material is what separates them. */
.k-bar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--k-bar-h);
  z-index: 100;   /* stays above the index overlay: the way out must remain visible */
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 16px;
  background: rgba(var(--sheet-rgb, 16,22,40), .72);
  border-bottom: 1px solid var(--hair2, rgba(255, 255, 255, .08));
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  font-family: 'JB', ui-monospace, monospace;
  color: var(--ink, #f4f6ff);
}

/* a bright top edge — light catching the near face of the material */
.k-bar::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .16), transparent);
}

.k-brand {
  display: flex;
  align-items: baseline;
  gap: 9px;
  font-family: 'BSD', 'Big Shoulders Display', sans-serif;
  font-weight: 800;
  font-size: 17px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink, #f4f6ff);
  white-space: nowrap;
}
.k-brand i {
  font-style: normal;
  color: var(--flood-b, #fffdf4);
  text-shadow: 0 0 10px rgba(var(--flood-b-rgb, 255,253,244), .85), 0 0 26px rgba(var(--flood-rgb, 248,243,221), .4);
}
.k-brand b {
  font-family: 'JB', ui-monospace, monospace;
  font-weight: 400;
  font-size: 9px;
  letter-spacing: .24em;
  color: var(--dim-t, #6b7694);
}

.k-where {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 12px;
  text-align: center;
}
.k-where .k-board {
  font-size: 9px;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--dim-t, #6b7694);
  white-space: nowrap;
}
.k-where .k-title {
  font-family: 'Outfit', system-ui, sans-serif;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: -.005em;
  color: var(--ink, #f4f6ff);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.k-where .k-count {
  font-size: 10px;
  letter-spacing: .14em;
  color: var(--dim-t, #6b7694);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.k-tools { display: flex; align-items: center; gap: 6px; }

.k-btn {
  appearance: none;
  border: 1px solid var(--hair2, rgba(255, 255, 255, .08));
  background: transparent;
  color: var(--ink, #f4f6ff);
  font: inherit;
  font-size: 9px;
  letter-spacing: .18em;
  text-transform: uppercase;
  padding: 8px 12px;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  transition: background .18s var(--k-ease), border-color .18s var(--k-ease),
              color .18s var(--k-ease), transform .12s ease-out;
}
.k-btn:hover { background: rgba(255, 255, 255, .06); border-color: rgba(255, 255, 255, .18); }
/* feedback belongs on the press, not the release */
.k-btn:active { transform: scale(.96); }
.k-btn[aria-pressed="true"] {
  color: var(--flood, #f8f3dd);
  border-color: color-mix(in srgb, var(--flood, #f8f3dd) 40%, transparent);
  background: color-mix(in srgb, var(--flood, #f8f3dd) 12%, transparent);
}
.k-btn:focus-visible { outline: 2px solid var(--flood, #f8f3dd); outline-offset: 2px; }
.k-btn svg { width: 11px; height: 11px; fill: none; stroke: currentColor; stroke-width: 1.6; }

.k-btn.k-icon { padding: 8px; width: 32px; height: 32px; justify-content: center; }
.k-btn[disabled] { opacity: .3; pointer-events: none; }

.k-kbd {
  font-size: 9px;
  padding: 1px 4px;
  border-radius: 3px;
  border: 1px solid var(--hair2, rgba(255, 255, 255, .1));
  color: var(--dim-t, #6b7694);
}

/* =================================================================== tabs
   The navigation Kimi never drew. The boards are the product's areas, so they
   are the tabs. Translucent, wearing the board's own tokens, floating over the
   work rather than boxing it in. */
.k-tabs {
  position: fixed;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  z-index: 95;
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 5px;
  border-radius: 999px;
  background: rgba(var(--sheet-rgb, 16,22,40), .82);
  border: 1px solid var(--hair2, rgba(255, 255, 255, .16));
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  box-shadow: 0 20px 50px -22px rgba(0, 0, 0, .9);
}

.k-tab {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 15px;
  border-radius: 999px;
  text-decoration: none;
  color: var(--dim-t, #6b7694);
  font-family: 'JB', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: .18em;
  text-transform: uppercase;
  white-space: nowrap;
  transition: color .2s var(--k-ease), background .2s var(--k-ease), transform .14s ease-out;
}
.k-tab svg {
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round;
}
.k-tab:hover { color: var(--ink, #f4f6ff); background: rgba(255, 255, 255, .05); }
.k-tab:active { transform: scale(.95); }
.k-tab:focus-visible { outline: 2px solid var(--flood, #f8f3dd); outline-offset: 2px; }

.k-tab[aria-current="page"] {
  color: var(--flood-b, #fffdf4);
  background: color-mix(in srgb, var(--flood, #f8f3dd) 14%, transparent);
}
.k-tab[aria-current="page"] svg { stroke-width: 2; }
.k-tab.k-tab-off { opacity: .3; pointer-events: none; }

/* board 02's palette switcher shares this corner — lift it clear */
html[data-k] .palswitch { bottom: 82px; }

/* ------------------------------------------------------------ side steppers
   Flanking the screen rather than stacked in the bar: the control sits next to
   the thing it moves, so no label is needed to explain it. */
.k-step {
  position: fixed;
  top: calc(var(--k-bar-h) + (100vh - var(--k-bar-h)) / 2);
  transform: translateY(-50%);
  z-index: 88;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  border: 1px solid var(--hair2, rgba(255, 255, 255, .08));
  background: rgba(var(--sheet-rgb, 16,22,40), .6);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  color: var(--ink, #f4f6ff);
  cursor: pointer;
  transition: background .2s var(--k-ease), transform .16s var(--k-ease), opacity .2s;
}
.k-step:hover { background: rgba(var(--sheet-rgb, 16,22,40), .9); }
.k-step:active { transform: translateY(-50%) scale(.93); }
.k-step:focus-visible { outline: 2px solid var(--flood, #f8f3dd); outline-offset: 3px; }
.k-step.prev { left: 18px; }
.k-step.next { right: 18px; }
.k-step[disabled] { opacity: 0; pointer-events: none; }
.k-step svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.7; }

/* ==================================================================== index
   Where am I, where can I go, what's there, how do I get out. */
.k-index {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: grid;
  place-items: start center;
  padding: calc(var(--k-bar-h) + 34px) 24px 40px;
  overflow-y: auto;
  background: rgba(var(--bg-rgb, 5,7,13), .78);
  backdrop-filter: blur(26px) saturate(140%);
  -webkit-backdrop-filter: blur(26px) saturate(140%);
  opacity: 0;
  pointer-events: none;
  transition: opacity .26s var(--k-ease);
}
.k-index.open { opacity: 1; pointer-events: auto; }
.k-index-inner { width: min(1080px, 100%); }

.k-index h2 {
  font-family: 'JB', ui-monospace, monospace;
  font-size: 9px;
  font-weight: 400;
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--dim-t, #6b7694);
  margin: 0 0 14px;
}
.k-index h2:not(:first-child) { margin-top: 34px; }

.k-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.k-card {
  display: block;
  width: 100%;
  text-align: left;
  appearance: none;
  cursor: pointer;
  padding: 15px 16px 16px;
  border-radius: 14px;
  border: 1px solid var(--hair2, rgba(255, 255, 255, .08));
  background: rgba(255, 255, 255, .022);
  color: var(--ink, #f4f6ff);
  font-family: 'Outfit', system-ui, sans-serif;
  transition: border-color .2s var(--k-ease), background .2s var(--k-ease), transform .16s var(--k-ease);
}
.k-card:hover { background: rgba(255, 255, 255, .055); border-color: rgba(255, 255, 255, .2); transform: translateY(-2px); }
.k-card:active { transform: translateY(0) scale(.99); }
.k-card:focus-visible { outline: 2px solid var(--flood, #f8f3dd); outline-offset: 2px; }
.k-card .n {
  font-family: 'JB', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: .2em;
  color: var(--dim-t, #6b7694);
  display: block;
  margin-bottom: 7px;
}
.k-card .t {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -.005em;
  display: block;
}
.k-card .m {
  font-family: 'JB', ui-monospace, monospace;
  font-size: 9px;
  letter-spacing: .1em;
  color: var(--dim-t, #6b7694);
  margin-top: 8px;
  display: block;
  text-transform: uppercase;
}
.k-card[aria-current="true"] {
  border-color: color-mix(in srgb, var(--flood, #f8f3dd) 55%, transparent);
  background: color-mix(in srgb, var(--flood, #f8f3dd) 10%, transparent);
}
.k-card[aria-current="true"] .n { color: var(--flood, #f8f3dd); }
.k-card.soon { opacity: .38; pointer-events: none; }

/* ------------------------------------------------------------- reduced motion
   Not "no feedback" — a gentler, non-vestibular equivalent. */
@media (prefers-reduced-motion: reduce) {
  html[data-k] .k-on.k-enter-fwd,
  html[data-k] .k-on.k-enter-back { animation: none; }
  .k-card:hover { transform: none; }
  .k-btn:active, .k-step:active { transform: none; }
  .k-step:active { transform: translateY(-50%); }
}

@media (prefers-reduced-transparency: reduce) {
  .k-bar, .k-step { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--bg, #05070d); }
  .k-index { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--bg, #05070d); }
}

/* --------------------------------------------------------------- narrow view */
/* in-between widths: shed the labels, keep the shape */
@media (max-width: 1024px) {
  .k-brand b { display: none; }
  .k-where .k-board { display: none; }
  .k-step { width: 38px; height: 38px; }
  .k-step.prev { left: 8px; }
  .k-step.next { right: 8px; }
  .k-tools .k-btn span.lbl { display: none; }
  .k-tools .k-btn { padding: 8px 10px; }
  .k-tools .k-btn .k-kbd { display: none; }
}

/* ================================================ phone: the frame comes off
   A drawn phone bezel inside a real phone is a mockup of the object you are
   already holding. Below this width the frame, its inset and its shadow are
   removed and Kimi's screen fills the viewport, so the design is judged at
   size rather than as a picture of itself. The bezel is mockup chrome, not
   app UI — nothing inside the screen changes. */
@media (max-width: 720px) {
  :root { --k-bar-h: 52px; --k-top: 0px; }

  html[data-k] body { padding-bottom: 0; }
  html[data-k] .wrap {
    padding: 0;
    min-height: 100vh;
    min-height: 100dvh;
    /* the screen's layout box is 430px wide whatever it is scaled to. Left
       unclipped it widens the layout viewport to 430 and the browser shows only
       the device's worth of it — measured: layout 430, visual 390, right edge
       clipped by 16px. Clipping here keeps the layout viewport honest. */
    overflow: hidden;
  }

  html[data-k] .phone {
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  html[data-k] .phone .scr {
    inset: 0;
    border-radius: 0;
  }
  /* the drawn notch and the fake 21:08 status bar are mockup chrome for the
     same reason the bezel is: you are holding a phone that has its own */
  html[data-k] .phone .notch,
  html[data-k] .phone .statusbar { display: none; }

  /* both of these would sit on top of a full-bleed screen. Palettes stay
     reachable on board 02 through #p=1, #p=5, #p=6. */
  html[data-k] .slot.k-on > .replay,
  html[data-k] .palswitch { display: none; }

  /* the bar becomes a floating layer over the screen's own status strip */
  .k-bar {
    height: var(--k-bar-h);
    padding: 0 8px;
    gap: 4px;
    background: rgba(var(--sheet-rgb, 16,22,40), .62);
  }
  .k-brand { display: none; }
  .k-where { gap: 8px; }
  .k-where .k-title { font-size: 13px; }
  .k-where .k-count { font-size: 9px; letter-spacing: .1em; }

  /* the steppers leave the sides of the screen and rejoin the flow, sitting
     either side of where-you-are instead of on top of the design */
  .k-step {
    position: static;
    transform: none;
    flex: none;
    width: 34px;
    height: 34px;
    background: transparent;
    border-color: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
  .k-step:hover { background: transparent; }
  .k-step:active { transform: scale(.9); }
  .k-step[disabled] { opacity: .2; pointer-events: none; }
  .k-step svg { width: 16px; height: 16px; }

  .k-tools { gap: 2px; }
  .k-tools .k-btn {
    padding: 0;
    width: 34px;
    height: 34px;
    justify-content: center;
    border-color: transparent;
  }
  .k-tools .k-btn svg { width: 15px; height: 15px; }
  /* "fit" has nothing left to mean once the screen fills the viewport */
  .k-tools .k-btn.k-fit { display: none; }

  /* a real bottom bar, in thumb reach, with room for the home indicator */
  .k-tabs {
    left: 0; right: 0; bottom: 0;
    transform: none;
    border-radius: 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    gap: 0;
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
    box-shadow: none;
  }
  .k-tab {
    flex: 1;
    flex-direction: column;
    gap: 4px;
    padding: 6px 2px;
    font-size: 8px;
    letter-spacing: .1em;
  }
  .k-tab svg { width: 18px; height: 18px; }

  /* Kimi's screens end flush at the bottom; give them room to scroll past the
     bar so nothing important sits permanently underneath it. Padding only —
     the composition above is untouched. */
  html[data-k] .phone .pscroll { padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }

  .k-index { padding: calc(var(--k-bar-h) + 18px) 14px 96px; }
  .k-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
  .k-card { padding: 13px 14px 14px; }
  .k-card .t { font-size: 13px; }
}
