/*
 * One stylesheet for everything at kamikaz.nativia.co - the site and the
 * privacy policy.
 *
 * The colours are not chosen here. They are the game's `Skin.Night`, copied
 * value for value out of `app/ui/Skin.kt`, and the two typefaces are the two
 * the game ships: Chakra Petch for the interface and the numbers, Bungee for
 * the handful of words it shouts. A site that invents its own palette next to
 * an app that already has one is two products wearing one name; the policy
 * page did exactly that for a while, on an orange that appears nowhere in the
 * game.
 *
 * The blocks below are the same construction as the launcher icon and the
 * menu logo: a moulded face, a lighter bar across the top, a shade along the
 * bottom, a darker stroke around it and a highlight dot in the corner. Drawing
 * the site's chips that way rather than as coloured rectangles is the whole
 * reason this page looks like this game and not like a template.
 */

:root {
    /* Skin.Night, verbatim. */
    --ground: #07080C;
    --ground-low: #04050A;
    --surface: #11131C;
    --surface-high: #1C1F2B;
    --outline: #2A2F40;
    --floor-line: #1A1E2B;
    --text: #E8EAF2;
    --muted: #8A90A6;
    --accent: #C6F03C;
    --on-accent: #0B0F02;

    /* The block families, used to colour what they actually are. */
    --bomb: #FF3B41;
    --charge: #FFB020;
    --frozen: #55C8E8;
    --purge: #9B7BE8;
    --beam: #7B5BFF;
    --candy: #FFF3C9;
    --blue: #4C7DF0;
    --teal: #24BE9C;
    --pink: #EE5FA7;
    --plum: #8E4FA8;
    --heart: #FF3D6E;

    --max-width: 1080px;
    --prose-width: 720px;

    --display: "Chakra Petch", "Segoe UI", system-ui, -apple-system, sans-serif;
    --poster: "Bungee", "Chakra Petch", Impact, sans-serif;

    color-scheme: dark;
}

* {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}

body {
    margin: 0;
    background: var(--ground);
    color: var(--text);
    font-family: var(--display);
    font-weight: 400;
    line-height: 1.7;
    -webkit-font-smoothing: antialiased;
}

a {
    color: var(--accent);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

.container {
    width: min(100% - 40px, var(--max-width));
    margin: 0 auto;
}

.prose {
    max-width: var(--prose-width);
}

/* ---------------------------------------------------------------- header - */

header {
    border-bottom: 1px solid var(--floor-line);
    padding: 20px 0;
    position: sticky;
    top: 0;
    z-index: 10;
    background: color-mix(in srgb, var(--ground) 92%, transparent);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
}

.header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
}

.brand {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--text);
    font-family: var(--poster);
    font-size: 17px;
    letter-spacing: 0.02em;
}

.brand:hover {
    text-decoration: none;
}

.brand-mark {
    width: 34px;
    height: 34px;
    flex: none;
    display: block;
}

.language {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 14px;
    color: var(--muted);
}

.language a {
    color: var(--muted);
}

.language a:hover {
    color: var(--text);
}

.language .current {
    color: var(--text);
    font-weight: 700;
}

.language .sep {
    color: var(--outline);
}

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

h1,
h2,
h3 {
    text-wrap: balance;
    line-height: 1.15;
    margin: 0;
}

h1 {
    font-family: var(--poster);
    font-size: clamp(40px, 8vw, 82px);
    letter-spacing: -0.01em;
}

h2 {
    font-size: clamp(24px, 3.4vw, 34px);
    font-weight: 700;
    letter-spacing: -0.01em;
    margin-bottom: 18px;
}

h3 {
    font-size: 18px;
    font-weight: 700;
    margin-bottom: 6px;
}

p {
    margin: 0 0 18px;
}

ul {
    margin: 0 0 18px;
    padding-left: 22px;
}

li {
    margin-bottom: 8px;
}

.eyebrow {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 18px;
}

.lede {
    font-size: clamp(17px, 2.2vw, 21px);
    color: var(--muted);
    max-width: 56ch;
}

.muted {
    color: var(--muted);
}

/* ------------------------------------------------- sections and the floor - */

main {
    padding: 0 0 40px;
}

section {
    padding: 72px 0;
    border-top: 1px solid var(--floor-line);
}

section:first-of-type {
    border-top: 0;
}

/*
 * The floor is what ends a run in this game, so it is what separates the
 * sections here: a hairline in the game's own floor colour, with the accent
 * marking where the eye should stop.
 */
.floor {
    position: relative;
}

.floor::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 0;
    width: 64px;
    height: 2px;
    background: var(--accent);
}

/* ------------------------------------------------------------- the blocks - */

/*
 * A moulded block, the launcher icon's recipe in three elements: the face is
 * the element itself, ::before is the light bar across the top, ::after is the
 * highlight dot. The shade along the bottom and the darker edge are an inset
 * shadow and a border, both derived from the block's own colour so a new block
 * type needs one custom property and nothing else.
 */
.block {
    --block: var(--normal, #5B6B8C);
    position: relative;
    display: grid;
    place-items: center;
    width: 46px;
    height: 46px;
    flex: none;
    border-radius: 10px;
    background: linear-gradient(
        180deg,
        color-mix(in srgb, var(--block) 88%, white) 0%,
        var(--block) 50%,
        color-mix(in srgb, var(--block) 78%, black) 100%
    );
    border: 1px solid color-mix(in srgb, var(--block) 45%, black);
    box-shadow: inset 0 -5px 0 rgba(0, 0, 0, 0.22);
    font-size: 18px;
    line-height: 1;
}

.block::before {
    content: "";
    position: absolute;
    inset: 3px 3px auto 3px;
    height: 7px;
    border-radius: 5px;
    background: rgba(255, 255, 255, 0.18);
}

.block::after {
    content: "";
    position: absolute;
    top: 8px;
    left: 8px;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.34);
}

.block-lg {
    width: 58px;
    height: 58px;
    border-radius: 13px;
}

/*
 * The mark a special block wears.
 *
 * `ui/Glyphs.kt` is emphatic about why these exist: colour alone cannot carry
 * a rule when one man in twelve cannot separate the red block from the amber
 * one. A chip without its glyph is not a simplified block, it is the wrong
 * block - and the site was showing five of them.
 *
 * They sit above the top bar and the highlight dot, as they do on the board.
 */
.block > img {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 62%;
    height: 62%;
}

/* ------------------------------------------------------------------ grids - */

.grid {
    display: grid;
    gap: 20px;
}

.grid-2 {
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}

.grid-3 {
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}

.card {
    background: var(--surface);
    border: 1px solid var(--outline);
    border-radius: 16px;
    padding: 24px;
}

.card p:last-child {
    margin-bottom: 0;
}

/* A card whose subject is one block type: the block sits above the words. */
.piece {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* --------------------------------------------------------------- the hero - */

.hero {
    padding: clamp(56px, 9vw, 104px) 0 clamp(48px, 7vw, 80px);
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: clamp(32px, 5vw, 64px);
    align-items: center;
}

@media (max-width: 860px) {
    .hero {
        grid-template-columns: minmax(0, 1fr);
    }
}

.tagline {
    font-family: var(--poster);
    font-size: clamp(15px, 2vw, 19px);
    color: var(--accent);
    letter-spacing: 0.02em;
    margin: 18px 0 22px;
}

.actions {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    align-items: center;
    margin-top: 30px;
}

/* The closing call sits under a centred row of screenshots, so it centres too. */
.actions-centred {
    justify-content: center;
    margin-top: 0;
}

/*
 * The raised key, the same object as the game's own buttons: a face that sits
 * on a thicker edge, and presses down onto it when you push it.
 */
.key {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 14px 24px;
    border-radius: 14px;
    font-weight: 700;
    font-size: 15px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    background: var(--accent);
    color: var(--on-accent);
    box-shadow: 0 5px 0 color-mix(in srgb, var(--accent) 55%, black);
    transition: transform 0.08s ease, box-shadow 0.08s ease;
}

.key:hover {
    text-decoration: none;
}

.key:active {
    transform: translateY(4px);
    box-shadow: 0 1px 0 color-mix(in srgb, var(--accent) 55%, black);
}

.key-quiet {
    background: var(--surface-high);
    color: var(--text);
    box-shadow: 0 5px 0 var(--ground-low);
}

.key-quiet:active {
    box-shadow: 0 1px 0 var(--ground-low);
}

/* ------------------------------------------------------------ screenshots - */

/*
 * A screenshot in a phone-shaped frame. The pictures are real captures of the
 * running game with the status bar and the gesture bar cropped off, so the
 * frame is the only furniture the page adds; it is there to say "this is a
 * screen", not to imitate a particular handset.
 *
 * The width cap matters. A 540px-wide capture stretched across a desktop
 * column is a blurry poster of a phone; held near its natural size it reads
 * as the game.
 */
.shot {
    /*
     * `width`, not `max-width`. As a grid item with `margin-inline: auto`, a
     * max-width box shrinks to fit its contents - and its contents are an
     * image asking for 100% of it, which resolves to nothing. The frame came
     * out 22px wide, the picture never loaded, and the section looked empty.
     */
    width: min(100%, 300px);
    margin-inline: auto;
    padding: 10px;
    background: var(--surface-high);
    border: 1px solid var(--outline);
    border-radius: 30px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
}

.shot img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 21px;
}

/*
 * Four screenshots on one line, on a wide screen.
 *
 * Four 300px frames need 1272px and the column is 1080, so they have to be
 * narrower here than they are on their own - 240 with a 20px gap comes to
 * 1020 and fits. The frames elsewhere on the page keep their 300, because
 * they are not competing for a row.
 *
 * They wrap on their own below that: two and two, then one under another.
 */
.shots {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    justify-content: center;
}

.shots .shot {
    width: min(100%, 240px);
    padding: 8px;
    border-radius: 26px;
}

.shots .shot img {
    border-radius: 19px;
}

/*
 * A picture on the left with its explanation on the right - the shape the
 * modes section wants, and one a `grid-2` cannot give it: `auto-fit` with a
 * 300px minimum splits the row into two equal halves, which makes the phone
 * as wide as four stacked cards and the cards as narrow as a phone. Here the
 * picture takes exactly its own width and the text takes the rest.
 *
 * It collapses to one column earlier than the other grids, because two
 * columns stop being two columns once the text side is narrower than the
 * picture beside it.
 */
.beside {
    display: grid;
    /*
     * A definite track, not `auto`. An `auto` track sizes to the item's
     * max-content, and the frame's max-content is the screenshot's intrinsic
     * 540px however narrow its own `width` is - so the picture sat centred in
     * a 562px lane of empty space while the cards were squeezed beside it.
     */
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    gap: clamp(24px, 4vw, 48px);
    align-items: start;
}

@media (max-width: 760px) {
    .beside {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* -------------------------------------------------------------- the modes - */

.mode {
    border-left: 3px solid var(--mode, var(--accent));
    padding-left: 18px;
}

.mode h3 {
    font-family: var(--poster);
    font-size: 15px;
    letter-spacing: 0.04em;
    color: var(--mode, var(--accent));
    margin-bottom: 8px;
}

.mode p {
    margin-bottom: 0;
    color: var(--muted);
}

/* --------------------------------------------------------------- the pull - */

/* One sentence given the weight of a headline. Used once per page at most. */
.pull {
    font-family: var(--poster);
    font-size: clamp(20px, 3vw, 30px);
    line-height: 1.3;
    color: var(--text);
    max-width: 22ch;
}

.pull em {
    font-style: normal;
    color: var(--accent);
}

/* ---------------------------------------------------------- policy chrome - */

/*
 * The privacy policy shares this sheet. What follows is only what that page
 * needs and this one does not.
 */

.updated {
    display: inline-block;
    margin-top: 14px;
    padding: 6px 14px;
    border-radius: 999px;
    background: var(--surface-high);
    border: 1px solid var(--outline);
    font-size: 13px;
    color: var(--muted);
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    margin: 24px 0;
    font-size: 15px;
}

.data-table th,
.data-table td {
    text-align: left;
    padding: 14px 16px;
    border-bottom: 1px solid var(--outline);
    vertical-align: top;
}

.data-table th {
    font-size: 12px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--muted);
    font-weight: 700;
}

.table-scroll {
    overflow-x: auto;
}

.highlight {
    color: var(--accent);
}

/*
 * The policy is read, not scanned, so it gets a measure rather than the site's
 * full column - about 75 characters, where the eye can find the next line
 * without hunting for it.
 */
.policy .container {
    width: min(100% - 40px, 780px);
}

/*
 * Two things the policy shares the *name* of with the site but not the
 * meaning. Its `.hero` is a block of text, not the site's two-column stage;
 * and its title is not one of the handful of words this game shouts, which is
 * the whole brief for Bungee - a legal document set in a poster face reads as
 * shouting at the reader it is meant to inform.
 */
.policy .hero {
    display: block;
    padding: clamp(48px, 7vw, 76px) 0 clamp(28px, 4vw, 44px);
}

.policy h1 {
    font-family: var(--display);
    font-weight: 700;
    font-size: clamp(30px, 4.6vw, 46px);
    letter-spacing: -0.02em;
}

.policy section {
    padding: 46px 0;
}

/* --------------------------------------------------------------- the foot - */

footer {
    border-top: 1px solid var(--floor-line);
    padding: 40px 0 56px;
    color: var(--muted);
    font-size: 14px;
}

.footer-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

.footer-links a {
    color: var(--muted);
}

.footer-links a:hover {
    color: var(--text);
}

.back-top {
    color: var(--muted);
}

@media (max-width: 640px) {
    section {
        padding: 56px 0;
    }

    /*
     * A three-column table of data practices does not fit a phone, and
     * squeezing it makes every cell a column of single words. It scrolls
     * sideways inside itself instead, so the page never does.
     */
    .data-table {
        display: block;
        overflow-x: auto;
        white-space: normal;
    }

    .data-table th,
    .data-table td {
        padding: 12px 10px;
        min-width: 140px;
    }
}
