/* Rack View giveaway: the app's look on the web. Golden pine rack, Master I/O
   metal faceplate, tape labels in marker, cobalt accents, LED meter. */
:root {
    --bg: #17181b;
    --bg-deep: #0e0f11;
    --ink: #17191c;
    --muted: #6d665b;
    --cobalt: #0a57ff;
    --led-on: #ffb347;
    --led-off: #3a2c1c;
    --green: #2e9b4f;
    --error: #b3261e;
    --tape: #efe6cf;
    --tape-edge: #d8ccad;
    --gutter: 16px;
    /* Spacing on an 8 px grid. */
    --s1: 8px;
    --s2: 16px;
    --s3: 24px;
    --s4: 32px;
    --s5: 40px;
    /* Type: 16 px body, 26 px title (16 x 1.618, the golden ratio), 20 px between
       (16 x sqrt 1.618); 15 / 12 px for reading copy and fine print. Lines on 8 px. */
    --fs-fine: 12px;
    --fs-copy: 15px;
    --fs-body: 16px;
    --fs-lead: 20px;
    --fs-title: 26px;
    --lh-copy: 24px;
}

* { box-sizing: border-box; }

html, body { margin: 0; }

/* Behind the page: Rack View itself, playing music (assets/rackview-backdrop.jpg,
   captured by tests/tools/rackview_showcase from the real AU with an empty rack),
   softly blurred and dimmed under a vignette. */
.backdrop {
    position: fixed;
    inset: -40px;
    z-index: -1;
    background: url("assets/rackview-backdrop.jpg") center bottom / cover no-repeat; /* keeps the spectrum and VU meters in view */
    filter: blur(7px) brightness(0.72) saturate(1.2);
}
.backdrop::after {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse at 50% 40%, rgba(14, 15, 17, 0.05) 0%, rgba(14, 15, 17, 0.35) 65%, rgba(14, 15, 17, 0.8) 100%);
}
body {
    min-height: 100vh;
    position: relative;
    isolation: isolate;
    background: radial-gradient(circle at 50% 0%, #26272b 0%, var(--bg) 45%, var(--bg-deep) 100%);
    color: var(--ink);
    font-family: Lexend, "Avenir Next", system-ui, sans-serif;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: var(--s3) var(--gutter) var(--s4);
}

/* The plug-in's title bar: 44 px, the same gradient and edge lines, and the brand
   image placed like the editor places it, with the gap between "rack view" and "by"
   (90 pt from the image's left edge) on the centre line. */
.brand {
    --brand-gap-x: 90px;
    align-self: stretch;
    position: relative;
    height: 44px;
    margin: calc(-1 * var(--s3)) calc(-1 * var(--gutter)) var(--s4);
    background: linear-gradient(180deg, #2a2d32, #1c1e21);
    border-top: 1px solid rgba(255, 255, 255, 0.145);
    border-bottom: 1px solid #0c0d0e;
    box-sizing: border-box;
}
.brand-image {
    position: absolute;
    top: -1px; /* the image is the full 44 px bar: start it under the top line, as in the editor */
    left: calc(50% - var(--brand-gap-x));
    width: 200px;
    height: 44px;
}
.lang { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); display: flex; gap: 4px; }
.lang button {
    font: 600 12px Lexend, system-ui, sans-serif;
    color: #bbb;
    background: transparent;
    border: 1px solid #44464b;
    border-radius: 4px;
    padding: 4px 7px;
    cursor: pointer;
}
.lang button[aria-pressed="true"] { color: #fff; border-color: #5fb3d9; }

/* The rack's golden pine, painted by the plug-in's RackWoodPainter and exported
   (tests/tools/web_assets_export): 39 px ears stretched to the rack's height, as
   the editor stretches its texture, and 19 px caps across the whole width,
   9-sliced so their 6 px rounded ends keep their shape. */
.rack { width: 100%; max-width: 720px; filter: drop-shadow(0 18px 40px rgba(0, 0, 0, 0.55)); }
.rack-cap {
    height: 19px;
    box-sizing: border-box;
    border-style: solid;
    border-width: 6px 6px 7px;
    border-image: url("assets/rack-cap-top@3x.png") 18 18 21 fill / 6px 6px 7px stretch;
    position: relative;
    z-index: 1; /* the caps lie over the ears' ends */
}
.rack-cap:last-child { border-image-source: url("assets/rack-cap-bottom@3x.png"); }
.rack-body { display: flex; align-items: stretch; }
.rack-ear { width: 39px; flex: none; background: url("assets/rack-ear-left@2x.png") 0 0 / 100% 100%; }
.rack-ear.right { background-image: url("assets/rack-ear-right@2x.png"); }

/* The faceplate in Master I/O's material (MasterIOSectionView::paint): the ivory
   gradient, its 128 px grain tile at 12% (assets/plate-grain.png, exported from the
   plug-in), contact shadows where it passes under the timber, a fine outline and
   a bright bevel, and the same black slotted screws 14 / 15 px in from the corners. */
.plate {
    position: relative;
    flex: 1;
    min-width: 0;
    padding: var(--s5);
    background:
        linear-gradient(180deg, rgba(0, 0, 0, 0.34), transparent 4px),
        linear-gradient(90deg, rgba(0, 0, 0, 0.32), transparent 4px),
        url("assets/plate-grain.png") 0 0 / 128px 128px repeat,
        linear-gradient(180deg, #d9d4bf 0%, #ede6d1 24%, #e0d9c4 64%, #c9c4b3 100%);
}
.plate::before { /* outline at 2 px in, 0.75 px; white bevel along the bottom and right */
    content: "";
    position: absolute;
    inset: 2px;
    border: 0.75px solid rgba(38, 40, 43, 0.39);
    box-shadow: inset -1px -1px 0 rgba(255, 255, 255, 0.42);
    pointer-events: none;
}
.screw { /* RackFaceplateMaterial::drawScrew: washer, head, one straight slot */
    position: absolute;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: radial-gradient(circle, rgb(51, 51, 51) 0 3.9px, rgba(11, 11, 11, 0.96) 3.9px);
    box-shadow: inset 0 0 0 0.4px rgba(77, 77, 77, 0.72), 0 0 0 0.4px rgba(77, 77, 77, 0.72);
}
.screw::after {
    content: "";
    position: absolute;
    left: 3.8px;
    top: 5.5px;
    width: 4.4px;
    height: 1px;
    background: rgba(9, 9, 9, 0.95);
}
.tl { top: 9px; left: 8px; } .tr { top: 9px; right: 8px; }
.bl { bottom: 9px; left: 8px; } .br { bottom: 9px; right: 8px; }

/* Masking tape with marker text. */
.tape {
    display: inline-block;
    background:
        repeating-linear-gradient(90deg, rgba(0, 0, 0, 0.025) 0 2px, transparent 2px 5px),
        var(--tape);
    border-left: 3px dotted var(--tape-edge);
    border-right: 3px dotted var(--tape-edge);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    font-family: Sriracha, "Marker Felt", cursive;
    color: #1d1d1d;
    transform: rotate(-1deg);
}
.tape-title { display: block; width: fit-content; margin: 0 auto var(--s3); padding: 4px var(--s2); }
.tape-title h1 { margin: 0; font: inherit; font-size: var(--fs-title); line-height: 1.25; letter-spacing: 0.5px; }
.tape-small { padding: 2px 10px; font-size: var(--fs-copy); line-height: 20px; }
.tape-green { background-color: #d6ecd2; }

.lead, .fine, .hint, .message { text-wrap: balance; }
.features span, .steps li, .thanks { text-wrap: pretty; }
.lead { text-align: center; color: #3b3832; margin: 0 0 var(--s1); font-size: var(--fs-lead); line-height: 1.4; }
.platform { text-align: center; color: var(--muted); margin: 0 0 var(--s4); font-size: var(--fs-copy); line-height: var(--lh-copy); letter-spacing: 0.2px; }
.platform span { display: block; }

/* Thank-you screen with the power button to hold. */
.intro { display: flex; flex-direction: column; align-items: stretch; }
.intro[hidden], .main[hidden] { display: none; }
.intro .thanks { margin: 0 0 var(--s3); }
.intro-hint { text-align: center; margin: 0 0 var(--s2); font-size: var(--fs-body); line-height: var(--lh-copy); color: #3b3832; text-wrap: balance; }
.power { display: flex; flex-direction: column; align-items: center; gap: var(--s3); }
.power .leds { width: 100%; }
.power .led { position: relative; }
.power .led::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: var(--led-on);
    box-shadow: 0 0 6px rgba(255, 179, 71, 0.75);
    opacity: var(--level, 0);
}
.phase-key.phase-key-power { width: 64px; height: 64px; }
.main { animation: power-up 0.5s ease both; }
@keyframes power-up { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
    .main { animation: none; }
}

.download { display: flex; flex-direction: column; gap: var(--s1); margin-top: var(--s2); animation: power-up 0.4s ease both; }
.download .tape { align-self: flex-start; }
.download .phase-key { margin: var(--s1) 0; }

/* The plug-in's Phase key (phase-key.js paints the canvas; the label stays in the DOM for i18n and screen readers). */
.phase-key {
    position: relative;
    display: block;
    width: 100%;
    height: 44px;
    padding: 0;
    border: 0;
    background: transparent;
    font: 600 var(--fs-body) Lexend, system-ui, sans-serif;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}
.phase-key-small { width: 96px; height: 30px; flex: none; }
.phase-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.phase-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
.phase-key:focus-visible { outline: 2px solid var(--cobalt); outline-offset: 3px; border-radius: 9px; }
.phase-key:disabled, .phase-key[aria-disabled="true"] { cursor: default; opacity: 0.6; }

/* LED meter of the keys left. */
.meter { margin: 0 0 var(--s4); }
.meter-label { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--s1); }
.meter-count { font-size: var(--fs-body); font-weight: 700; font-variant-numeric: tabular-nums; color: var(--ink); }
.leds {
    display: grid;
    grid-template-columns: repeat(20, 1fr);
    gap: 3px;
    padding: 6px;
    background: #121314;
    border-radius: 4px;
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.7);
}
.led { height: 10px; border-radius: 2px; background: var(--led-off); }
.led.on { background: var(--led-on); box-shadow: 0 0 6px rgba(255, 179, 71, 0.75); }

.features {
    margin: 0 0 var(--s5);
    padding: 0;
    list-style: none;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s3) var(--s4);
}
/* Each feature lit by a small amber LED, like the meters' segments. */
.features li { position: relative; padding-left: var(--s3); }
.features li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 8px; /* centred on the title's 24 px line */
    width: 8px;
    height: 8px;
    border-radius: 2px;
    background: var(--led-on);
    box-shadow: 0 0 6px rgba(255, 179, 71, 0.75);
}
.features strong { display: block; font-size: var(--fs-body); line-height: var(--lh-copy); font-weight: 700; color: var(--ink); }
.features span { display: block; font-size: var(--fs-copy); line-height: var(--lh-copy); color: #4a463e; }

/* Once the key is out, the features have done their job: the key comes up under the title. */
.main:has(.result:not([hidden])) .features { display: none; }

/* The claim form. */
.claim { display: flex; flex-direction: column; gap: var(--s2); }
.claim label { align-self: flex-start; margin-bottom: calc(-1 * var(--s1)); } /* the tape sits close to its field */
.claim input {
    font: var(--fs-body) Lexend, system-ui, sans-serif;
    height: 48px;
    padding: 0 var(--s2);
    border: 1px solid rgba(109, 102, 91, 0.55);
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.75);
    color: var(--ink);
}
.claim input:focus { outline: 2px solid var(--cobalt); outline-offset: 1px; }
.turnstile { min-height: 65px; }

.message { min-height: var(--lh-copy); margin: 0; font-size: var(--fs-copy); line-height: var(--lh-copy); color: var(--ink); }
.message:empty { min-height: 0; margin-top: calc(-1 * var(--s2)); } /* no blank line under the button */
.message.error { color: var(--error); }

.result { display: flex; flex-direction: column; gap: var(--s2); }
.result[hidden], .claim[hidden] { display: none; }
.result .tape { align-self: flex-start; }
.result > .tape { margin-bottom: calc(-1 * var(--s1)); }
.key-display {
    display: flex;
    align-items: center;
    gap: var(--s2);
    background: #121314;
    border-radius: 5px;
    padding: var(--s2);
    box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.7);
}
.key-display code {
    flex: 1;
    min-width: 0;
    color: var(--led-on);
    font: 600 var(--fs-lead) ui-monospace, "SF Mono", Menlo, monospace;
    letter-spacing: 1px;
    overflow-wrap: anywhere;
    text-shadow: 0 0 8px rgba(255, 179, 71, 0.5);
}
.hint { margin: 0; font-size: var(--fs-copy); line-height: var(--lh-copy); color: var(--muted); }
.steps { margin: var(--s2) 0 0; padding: 0; list-style: none; counter-reset: step; font-size: var(--fs-body); line-height: var(--lh-copy); color: #2d2b27; }
.steps li { counter-increment: step; position: relative; padding-left: var(--s3); } /* numbers on the content edge, text on the features' text line */
.steps li + li { margin-top: var(--s1); }
.steps li::before { content: counter(step) "."; position: absolute; left: 0; font-weight: 700; }

.thanks {
    margin: 0;
    padding: var(--s2) var(--s3);
    font-size: var(--fs-copy);
    line-height: var(--lh-copy);
    color: #2d2b27;
    background: rgba(255, 255, 255, 0.45);
    border-left: 3px solid var(--cobalt);
    border-radius: 4px;
}
.thanks p { margin: 0; }
.thanks .thanks-lead { font-style: italic; color: var(--muted); }
.thanks p + p { margin-top: var(--s1); }
.fine { margin: var(--s4) 0 0; font-size: var(--fs-fine); line-height: 20px; color: var(--muted); text-align: center; }
.foot { color: #8b8e94; font-size: var(--fs-fine); margin-top: var(--s3); letter-spacing: 0.2px; }

/* Laptops and desktops: the same order from top to bottom, but a wider rack and type a
   step smaller, so the plate is landscape (about 4:3) and fits one 13-15" screen. */
@media (min-width: 960px) {
    :root {
        --fs-fine: 11px;
        --fs-copy: 12px;
        --fs-body: 15px;
        --fs-lead: 16px;
        --fs-title: 22px;
        --lh-copy: 20px;
    }
    .rack { max-width: 1100px; }
    .rack:has(.intro:not([hidden])) { max-width: 960px; } /* the letter is shorter: keep that plate near 5:3 too */
    .plate { padding: var(--s4) var(--s5); }
    .tape-title { margin-bottom: var(--s2); }
    .platform { margin-bottom: var(--s3); }
    .meter { margin-bottom: var(--s3); }
    .features { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s2) var(--s4); margin-bottom: var(--s4); }
    /* The form as one narrow column in the middle: email, the Turnstile check under it, then the key button. */
    .claim { width: 100%; max-width: 440px; margin-inline: auto; }
    .fine { margin-top: var(--s3); }

    /* The letter keeps a comfortable line length (about 75 characters). */
    .intro .thanks, .intro-hint, .power { width: 100%; max-width: 760px; margin-inline: auto; }
    .intro .thanks { font-size: var(--fs-body); line-height: var(--s3); }
    .power { gap: var(--s2); }
}

@media (max-width: 760px) {
    .features { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
    .brand { margin-bottom: 56px; }
    .lang { top: auto; bottom: -40px; right: 50%; transform: translateX(50%); }
    .rack-ear { width: 24px; } /* phones: narrower ears leave room for the plate */
    .backdrop { background-position: 88% bottom; } /* phones: the VU meters and Master I/O */
    .plate { padding: var(--s4) var(--s2) var(--s3); }
    .features { gap: var(--s2); }
    .thanks { padding: var(--s2); } /* phones: keep the letter's lines long enough to read */
    :root { --fs-title: 22px; --fs-lead: 18px; }
    .key-display { flex-direction: column; align-items: stretch; }
    .phase-key-small { width: 100%; }
    .key-display code { font-size: var(--fs-body); text-align: center; }
}

@media (max-width: 360px) {
    .rack-ear { width: 18px; }
    .plate { padding-left: 12px; padding-right: 12px; }
    :root { --fs-copy: 15px; --fs-body: 15px; --fs-lead: 16px; --fs-title: 18px; }
    .tape-title { white-space: nowrap; }
}
