/* The three keynote screens, as they render on the wall.
 *
 * SOURCE OF TRUTH — do not re-derive these numbers. Every coordinate here is
 * transcribed verbatim from the Aura fragments' stylesheets:
 *
 *   src/assets/js/app/fragments/pages/Keynote53.module.scss
 *   src/assets/js/app/fragments/pages/Keynote55.module.scss
 *   src/assets/js/app/fragments/pages/Keynote56.module.scss
 *
 * Tokens come from src/assets/css/global.scss, faces from
 * src/assets/css/utils/typography.scss. If a layout changes in Figma, change it
 * there first and re-transcribe, then diff a preview against
 * docs/verification/keynote/keynote-53.jpg, -55.jpg, -56.jpg.
 *
 * Curation carries a copy rather than importing the fragments because it runs
 * standalone in Docker with no Aura build.
 *
 * Authored in raw Figma pixels inside a 3772 x 820 canvas. KeynoteScale scales
 * it uniformly; here keynote.js does the same with a CSS transform.
 */

@font-face {
    font-family: 'Reckless Neue';
    src: url('/assets/fonts/reckless-neue-100.woff2') format('woff2');
    font-weight: 100;
    font-style: normal;
    font-display: block;
}

@font-face {
    font-family: 'Reckless Neue';
    src: url('/assets/fonts/reckless-neue-100-italic.woff2') format('woff2');
    font-weight: 100;
    font-style: italic;
    font-display: block;
}

@font-face {
    font-family: 'Reckless Neue';
    src: url('/assets/fonts/reckless-neue-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: block;
}

@font-face {
    font-family: 'White Angelica';
    src: url('/assets/fonts/white-angelica-400.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: block;
}

:root {
    --keynote-ink: #202124;
    --keynote-paper: #f4f4f0;
    --keynote-body: #000000;
    --keynote-rule: #202124;
    --keynote-display: "Reckless Neue", Georgia, serif;
    --keynote-script: "White Angelica", "Snell Roundhand", cursive;
}

/* --- frame -------------------------------------------------------------- */

.kn-frame {
    position: relative;
    width: 100%;
    aspect-ratio: 3772 / 820;
    overflow: hidden;
    background: var(--keynote-paper);
}

.kn-stage {
    position: absolute;
    top: 0;
    left: 0;
    width: 3772px;
    height: 820px;
    overflow: hidden;
    transform-origin: top left;
    color: var(--keynote-ink);
    background: var(--keynote-paper);
}

/* Layout 53 is a transparent HUD over the ocean, not paper. */
.kn-stage.kn-53 { background: transparent; }

.kn-rule {
    position: absolute;
    height: 1.5px;
    background: var(--keynote-rule);
}

/* One drawing per screen, placed at the area the layout leaves for it.
   Geometry comes from artTokens.js; the element only has to hold it. */
.kn-region {
    position: absolute;
    overflow: hidden;
}

/* Nothing drawn for this screen yet — a faint dashed area so the space the
   drawing will fill is legible rather than invisible. */
.kn-region.is-reference {
    border: 1.5px dashed rgba(32, 33, 36, 0.14);
    border-radius: 3px;
}

.kn-region.kn-slot-drawing {
    border-color: rgba(32, 33, 36, 0.3);
    animation: slotPulse 1.6s ease-in-out infinite;
}

/* Generated drawings are raster on a near-white ground.

   `darken` takes the darker of image and paper per channel, so anywhere the
   ground is lighter than the cream it becomes exactly the cream and the ink
   stays ink. That alone is not enough: the model sometimes returns a ground
   with a faint blue cast (236,239,244 rather than white), which is *darker*
   than the cream and shows as a tinted rectangle. The filter lifts the light
   end to true white first — a levels move, near enough — at the cost of the
   line going a shade deeper, which at hairline weight does not read. */
.kn-art {
    pointer-events: none;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: fill;
    /* grayscale because the palette token says the art is ink only — it also
       strips any colour the model let into the line. */
    filter: grayscale(1) brightness(1.05) contrast(1.25);
    mix-blend-mode: darken;
}

.kn-art[data-phase="enter"] { animation: knEnter 1.4s cubic-bezier(0.16, 1, 0.3, 1) both; }
.kn-art[data-phase="idle"]  { animation: knIdle 11s ease-in-out infinite; }
.kn-art[data-phase="exit"]  { animation: knExit 1s ease-in both; }

@keyframes knEnter { from { opacity: 0; transform: translateY(6px) scale(0.995); } to { opacity: 1; transform: none; } }
@keyframes knIdle  { 0%, 100% { transform: translateY(0) } 50% { transform: translateY(-4px) } }
@keyframes knExit  { to { opacity: 0; } }

/* Inline SVG is ink on nothing — no ground to blend away, and it runs its own
   keyframes off the root's data-phase, so the host animation is not applied. */
.kn-art--svg {
    filter: none;
    mix-blend-mode: normal;
    animation: none;
}

.kn-art--svg svg { width: 100%; height: 100%; display: block; }

@media (prefers-reduced-motion: reduce) {
    .kn-art { animation: none !important; }
}

/* --- shared type -------------------------------------------------------- */

.kn-label {
    position: absolute;
    display: flex;
    flex-direction: column;
    justify-content: center;
    font-family: var(--keynote-display);
    font-weight: 100;
    font-size: 45px;
    line-height: 0.92;
    /* In em so shrinking the face brings the tracking with it. */
    letter-spacing: -0.05em;
    text-transform: capitalize;
    font-feature-settings: "case" 1, "liga" 0;
}

/* A label is always two lines, the way every Figma label is drawn — one word
   per line, so "Swell / from" and "Average / Period" keep their own shape and
   a one-word label still sits at the top of its box rather than centring in
   it. `nowrap` so a long word overhangs its box instead of breaking in half;
   keynote.js shrinks the face to keep that overhang small. */
.kn-line { display: block; line-height: 0.92; white-space: nowrap; }

.kn-value {
    position: absolute;
    font-family: var(--keynote-script);
    font-weight: 400;
    line-height: 1.4;
    text-align: right;
    /* `pre` not `nowrap`: the values carry a meaningful trailing space
       between the number and its unit ("3.0 FT"), which `nowrap` collapses. */
    white-space: pre;
    /* The number and its unit ride on the wrap's size, so a reading too wide
       for its slot comes down as one piece rather than in two steps. */
    font-size: 75px;
}

.kn-num  { font-size: 1em; line-height: 1.4; }
.kn-unit { font-size: 0.8em; line-height: 1.4; }

.kn-stamp {
    position: absolute;
    top: 100px;
    height: 68px;
    font-family: var(--keynote-display);
    font-weight: 100;
    font-size: 100px;
    line-height: 0.92;
    letter-spacing: -5px;
    text-transform: capitalize;
    font-feature-settings: "case" 1, "liga" 0;
    white-space: nowrap;
}

.kn-body {
    position: absolute;
    top: 268px;
    margin: 0;
    width: 1092px;
    height: 383px;
    color: var(--keynote-body);
    font-family: var(--keynote-script);
    font-weight: 400;
    font-size: 45px;
    line-height: 1.25;
    letter-spacing: -2.25px;
}

.kn-sparkle { position: absolute; width: 40px; height: 40px; }

.kn-caption {
    position: absolute;
    display: flex;
    align-items: center;
    font-family: var(--keynote-display);
    font-weight: 100;
    font-size: 45px;
    line-height: 1.15;
    letter-spacing: -2.25px;
    font-feature-settings: "case" 1, "liga" 0;
    white-space: nowrap;
}

/* ======================================================================== */
/* Keynote 53 — transparent HUD over the live ocean                         */
/* ======================================================================== */

.kn-53 .kn-backdrop {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* A 1.5px border-width rounds to 1px in Chrome, and a border would also shift
   the absolutely-positioned children's containing block. Draw the rule as an
   element instead, offset -0.75 so the 1.5px stroke straddles the Figma x. */
.kn-53 .kn-cell {
    position: absolute;
    top: 37px;
    height: 163px;
}

.kn-53 .kn-cell::before {
    content: "";
    position: absolute;
    top: 0;
    left: -0.75px;
    width: 1.5px;
    height: 163px;
    background: var(--keynote-rule);
}

.kn-53 .kn-cellSwell     { left: 50px; }
.kn-53 .kn-cellSwellFrom { left: 650px; }
.kn-53 .kn-cellPeriod    { left: 1250px; }
.kn-53 .kn-cellDate      { left: 1850px; }
.kn-53 .kn-cellTime      { left: 2450px; }

.kn-53 .kn-label {
    top: 13px;
    height: 50px;
    display: block;
    white-space: nowrap;
}

.kn-53 .kn-value {
    top: 63px;
    display: flex;
    height: 100px;
    align-items: flex-end;
    text-align: left;
}

.kn-53 .kn-cellSwell .kn-label,
.kn-53 .kn-cellSwell .kn-value     { left: 47.5px; }
.kn-53 .kn-cellSwellFrom .kn-label,
.kn-53 .kn-cellSwellFrom .kn-value { left: 49px; }
.kn-53 .kn-cellPeriod .kn-label,
.kn-53 .kn-cellPeriod .kn-value    { left: 49px; }
.kn-53 .kn-cellDate .kn-label,
.kn-53 .kn-cellDate .kn-value      { left: 49px; }
.kn-53 .kn-cellTime .kn-label,
.kn-53 .kn-cellTime .kn-value      { left: 49px; }

.kn-53 .kn-cellSwell     .kn-value { width: 275px; }
.kn-53 .kn-cellSwellFrom .kn-value { width: 274px; }
.kn-53 .kn-cellPeriod    .kn-value { width: 274px; }
.kn-53 .kn-cellDate      .kn-value { width: 329px; }
.kn-53 .kn-cellTime      .kn-value { width: 448px; }

.kn-53 .kn-degree {
    position: absolute;
    top: 85.9px;
    left: 184.9px;
    width: 35.2265px;
    height: 15.75px;
}

.kn-53 .kn-logo {
    position: absolute;
    top: 335px;
    left: 1581.59px;
    width: 608.813px;
    height: 149.99px;
}

.kn-53 .kn-gemini {
    position: absolute;
    top: 37px;
    left: 3291px;
    height: 163px;
}

.kn-53 .kn-sparkle { top: 0; left: 0; }

.kn-53 .kn-caption {
    top: 13px;
    left: 123px;
    width: 319px;
    display: block;
    white-space: normal;
}

/* The rule sits between the sparkle and the caption, at x 3380. */
.kn-53 .kn-gemini::before {
    content: "";
    position: absolute;
    top: 0;
    left: 88.25px;
    width: 1.5px;
    height: 163px;
    background: var(--keynote-rule);
}

/* ======================================================================== */
/* Keynote 55 — stats left / photo + kelp centre / insight right             */
/* ======================================================================== */

.kn-55 .kn-ruleA { top: 99.25px;  left: 100px; width: 559px; }
.kn-55 .kn-ruleB { top: 217.25px; left: 100px; width: 559px; }
.kn-55 .kn-ruleC { top: 342.25px; left: 100px; width: 559px; }
.kn-55 .kn-ruleD { top: 470.25px; left: 100px; width: 559px; }

.kn-55 .kn-labelOne  { top: 120px; left: 101px; width: 121px; height: 82px; }
.kn-55 .kn-labelTwo   { top: 234px; left: 101px; width: 207px; height: 91px; }
.kn-55 .kn-labelThree { top: 359px; left: 101px; width: 207px; height: 91px; }

.kn-55 .kn-valueOne  { top: 109px; left: 371px; width: 255px; height: 79px; }
.kn-55 .kn-valueTwo   { top: 234px; left: 385px; width: 274px; height: 93px; }
.kn-55 .kn-valueThree { top: 359px; left: 433px; width: 226px; height: 93px; }

.kn-55 .kn-degree {
    position: absolute;
    top: 257.9px;
    left: 551.9px;
    width: 35.2265px;
    height: 15.75px;
}

.kn-55 .kn-shell {
    position: absolute;
    top: 605.617px;
    width: 138.55px;
    height: 113.132px;
}

.kn-55 .kn-shellA { left: 100.2485px; }
.kn-55 .kn-shellB { left: 310.2485px; }
.kn-55 .kn-shellC { left: 521.2485px; }

.kn-55 .kn-photoFrame {
    position: absolute;
    top: 100px;
    left: 937px;
    width: 880px;
    height: 620px;
    overflow: hidden;
}

.kn-55 .kn-photo {
    position: absolute;
    top: -0.04%;
    left: -23.36%;
    width: 123.3%;
    height: 116.65%;
    max-width: none;
}

.kn-55 .kn-kelp {
    position: absolute;
    top: 27.351px;
    left: 1424.994px;
    width: 869.686px;
    height: 798.798px;
}

.kn-55 .kn-stampDate { left: 2565px; width: 565px; }
.kn-55 .kn-stampTime { left: 3302px; width: 370px; text-align: right; }

.kn-55 .kn-squiggle {
    position: absolute;
    top: 126.25px;
    left: 2961px;
    width: 301px;
    height: 15.5px;
}

.kn-55 .kn-ruleTop    { top: 217.25px; left: 2572px; width: 1105px; }
.kn-55 .kn-ruleBottom { top: 639.25px; left: 2572px; width: 1105px; }

.kn-55 .kn-body { left: 2585px; }
.kn-55 .kn-sparkle { top: 685px; left: 2572px; }
.kn-55 .kn-caption { top: 680px; left: 2637px; width: 815px; height: 50px; }

/* ======================================================================== */
/* Keynote 56 — insight left / fish + currents centre / stats + photo right  */
/* ======================================================================== */

.kn-56 .kn-stampDate { left: 100px; width: 565px; }
.kn-56 .kn-stampTime { left: 837px; width: 370px; text-align: right; }

.kn-56 .kn-squiggle {
    position: absolute;
    top: 126.25px;
    left: 496px;
    width: 301px;
    height: 15.5px;
}

.kn-56 .kn-ruleTop    { top: 217.25px; left: 107px; width: 1105px; }
.kn-56 .kn-ruleBottom { top: 639.25px; left: 107px; width: 1105px; }

.kn-56 .kn-body { left: 120px; }
.kn-56 .kn-sparkle { top: 685px; left: 107px; }
.kn-56 .kn-caption { top: 680px; left: 172px; width: 815px; height: 50px; }

/* Exports are stroke-expanded, so each is centred on its Figma node box. */
.kn-56 .kn-currents {
    position: absolute;
    top: 296.507px;
    left: 1676.27px;
    width: 1124.46px;
    height: 577.986px;
}

/* The fish are drawn upright and rotated in place, matching Figma. */
.kn-56 .kn-fishBox {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
}

.kn-56 .kn-fishBoxA { top: 55px; left: 1739px; width: 304.771px; height: 253.173px; }
.kn-56 .kn-fishBoxB { top: 572.65px; left: 1857px; width: 256.272px; height: 196.046px; }

.kn-56 .kn-fish { flex: none; }
.kn-56 .kn-fishA { width: 262.5px; height: 178.5px; transform: rotate(-19.26deg); }
.kn-56 .kn-fishB { width: 229.274px; height: 140.866px; transform: rotate(15.86deg); }

.kn-56 .kn-fishHost { position: absolute; inset: 0; }

.kn-56 .kn-ruleC1Top    { top: 99.25px;  left: 2408px; width: 392px; }
.kn-56 .kn-ruleC1Bottom { top: 217.25px; left: 2408px; width: 392px; }
.kn-56 .kn-ruleC2Top    { top: 99.25px;  left: 2850px; width: 392px; }
.kn-56 .kn-ruleC2Bottom { top: 217.25px; left: 2850px; width: 392px; }
.kn-56 .kn-ruleC3Top    { top: 99.25px;  left: 3292px; width: 380px; }
.kn-56 .kn-ruleC3Bottom { top: 217.25px; left: 3292px; width: 380px; }

.kn-56 .kn-labelOne  { top: 115px; left: 2409px; width: 164px; height: 82px; }
.kn-56 .kn-labelTwo   { top: 111px; left: 2851px; width: 144px; height: 91px; }
/* Figma starts this label 12px left of its own rule; that overhang is real. */
.kn-56 .kn-labelThree { top: 111px; left: 3280px; width: 146px; height: 91px; }

.kn-56 .kn-valueOne  { top: 104px; left: 2485px; width: 291px; height: 79px; }
.kn-56 .kn-valueTwo   { top: 111px; left: 2937px; width: 305px; height: 93px; }
.kn-56 .kn-valueThree { top: 108px; left: 3407px; width: 265px; height: 93px; }

.kn-56 .kn-degree {
    position: absolute;
    top: 139.9px;
    left: 3137.9px;
    width: 24.2px;
    height: 16.2px;
}

/* Source is portrait; Figma rotates it 90deg inside a 1264 x 452 frame. */
.kn-56 .kn-photoFrame {
    position: absolute;
    top: 268px;
    left: 2408px;
    width: 1264px;
    height: 452px;
    overflow: hidden;
}

.kn-56 .kn-photoRot {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 452px;
    height: 1264px;
    overflow: hidden;
    transform: translate(-50%, -50%) rotate(90deg);
}

.kn-56 .kn-photo {
    position: absolute;
    top: -2.1%;
    left: -30.16%;
    width: 164.44%;
    height: 104.55%;
    max-width: none;
}
