/*
    MTG Folder on the web — Illuminated Binder.

    The same design system the desktop and mobile builds are drawn from
    (docs/design/v080-visual-direction.md), not an approximation of it. Anything here that
    cannot be traced to a line in that document is a mistake to fix rather than a variation
    to keep.

    Card stock on a dark desk, lit from one warm lamp. The rail is the binder's spine. Violet
    is the working accent; gold is the mark of value, never decoration. Depth is stacked stock —
    a hard one-pixel lower edge — and never a blurred glow; the one exception the document
    allows is the lamp behind the brand and the empty states.

    One file and no framework. What it has to do that the desktop does not: become a phone
    application when it is installed from a phone browser, which is the media query at the foot
    rather than a second stylesheet.
*/

/* ---- the faces ---------------------------------------------------------------------- */
/*
    Self-hosted, and the same files the installed applications ship. Google's copies would be
    a third party in the request path and would not be in the service worker's cache, so an
    installed page opened on a train would fall back to a system sans and stop looking like
    the product at exactly the moment it is being relied on.
*/
@font-face {
    font-family: "Spectral";
    src: url("fonts/Spectral-SemiBold.ttf") format("truetype");
    font-weight: 600;
    font-display: swap;
}

@font-face {
    font-family: "Open Sans";
    src: url("fonts/OpenSans-Regular.ttf") format("truetype");
    font-weight: 400;
    font-display: swap;
}

@font-face {
    font-family: "Open Sans";
    src: url("fonts/OpenSans-Semibold.ttf") format("truetype");
    font-weight: 600;
    font-display: swap;
}

@font-face {
    font-family: "IBM Plex Mono";
    src: url("fonts/IBMPlexMono-Medium.ttf") format("truetype");
    font-weight: 500;
    font-display: swap;
}

:root {
    /* Surfaces: desk, mat, card stock, raised stock, pressed. */
    --desk: #07060C;
    --mat: #0E0C18;
    --stock: #151226;
    --stock-raised: #1C1830;
    --stock-pressed: #262042;

    --stroke-faint: #1F1B35;
    --stroke: #2C2649;
    --stroke-strong: #3D3568;

    --ink: #F3F0FA;
    --ink-muted: #B1A9CF;
    --ink-faint: #756D98;
    --ink-disabled: #4E477A;

    /* Violet works; gold marks value. Gold that has to be read is the brighter one — #D9A94A
       is 3.1:1 on the desk and fails AA, so it is for rules and brackets only. */
    --accent: #8A6CFF;
    --accent-pressed: #372A78;
    --gold: #F0CE7E;
    --gold-rule: #D9A94A;
    --gold-soft: #3A2E16;

    --success: #4FBF8B;
    --warning: #E0B15C;
    --danger: #E2568C;

    --display: "Spectral", "Iowan Old Style", Georgia, serif;
    --body: "Open Sans", "Segoe UI", system-ui, -apple-system, sans-serif;
    --mono: "IBM Plex Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

    --rail: 260px;

    color-scheme: dark;
}

* {
    box-sizing: border-box;
}

html {
    /* So the rubber-band area at the top of an installed iOS page is the desk, not white. */
    background: var(--desk);
}

body {
    margin: 0;
    background: var(--desk);
    color: var(--ink);
    font-family: var(--body);
    font-size: 14px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

/* ---- the shell: spine, then workspace ----------------------------------------------- */

.shell {
    display: grid;
    grid-template-columns: var(--rail) minmax(0, 1fr);
    min-height: 100vh;
    min-height: 100dvh;
}

/*
    The rail is the binder's spine: the brand in a pool of gold light over leather, the
    destinations below it, the version at the foot. The three ring wells on its outer edge are
    drawn as depth rather than as decoration lines, which is the one place a gradient earns
    its place here.
*/
.spine {
    position: relative;
    background: var(--desk);
    border-right: 1px solid var(--stroke-faint);
    display: flex;
    flex-direction: column;
    padding: 0 0 1rem;
}

.spine::after {
    /* The rings. Three wells down the spine's outer edge: a dark centre with a gold rim. */
    content: "";
    position: absolute;
    top: 6rem;
    left: 6px;
    width: 10px;
    height: 13rem;
    background:
        radial-gradient(circle at 5px 8px, #000 0 3px, var(--gold-rule) 3px 4px, transparent 4px),
        radial-gradient(circle at 5px 50%, #000 0 3px, var(--gold-rule) 3px 4px, transparent 4px),
        radial-gradient(circle at 5px calc(100% - 8px), #000 0 3px, var(--gold-rule) 3px 4px, transparent 4px);
    opacity: 0.55;
    pointer-events: none;
}

.brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    padding: 1.6rem 1rem 1.4rem;
    text-decoration: none;
    color: var(--ink);
    border-bottom: 1px solid var(--stroke-faint);
    /* The lamp. One of exactly two places the document allows soft light. */
    background: radial-gradient(ellipse 70% 55% at 50% 38%, rgba(240, 206, 126, 0.13), transparent 70%);
}

.brand img {
    width: 84px;
    height: 84px;
    image-rendering: auto;
}

.brand .wordmark {
    font-family: var(--display);
    font-weight: 600;
    font-size: 1.05rem;
    letter-spacing: 0.26em;
    text-transform: uppercase;
}

.brand .tagline {
    font-size: 11px;
    color: var(--ink-faint);
    letter-spacing: 0.04em;
}

.spine nav {
    display: flex;
    flex-direction: column;
    padding: 0.75rem 0.5rem;
    gap: 2px;
}

/*
    The rail has room for every destination, so More is not one of them here: it is the phone
    bar's fifth column standing in for the four it cannot hold.
*/
.spine nav .only-phone {
    display: none;
}

.spine nav a,
.spine nav button {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid transparent;
    border-radius: 8px;
    background: none;
    font: inherit;
    font-family: var(--display);
    font-weight: 600;
    font-size: 15px;
    color: var(--ink-muted);
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.spine nav a:hover,
.spine nav button:hover {
    background: var(--mat);
    color: var(--ink);
}

/* Selected: a fill and a hairline, plus the gold rule on the spine side. Never colour alone. */
.spine nav a.here {
    background: var(--stock);
    border-color: var(--stroke);
    color: var(--ink);
    box-shadow: inset 2px 0 0 var(--gold-rule);
}

.spine nav img {
    width: 22px;
    height: 22px;
    /* Pixel relics, so they are scaled by nearest neighbour rather than blurred. */
    image-rendering: pixelated;
}

.spine .foot {
    margin-top: auto;
    padding: 0 1.25rem;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--ink-disabled);
}

main {
    padding: 1.75rem 2rem 4rem;
    max-width: 68rem;
}

/* ---- type ---------------------------------------------------------------------------- */

h1 {
    font-family: var(--display);
    font-weight: 600;
    font-size: 24px;
    margin: 0 0 0.35rem;
    text-wrap: balance;
}

h2 {
    font-family: var(--display);
    font-weight: 600;
    font-size: 17px;
    margin: 2rem 0 0.6rem;
}

/* An overline, not a heading: the label above a group, tracked and small. */
.overline {
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

.kicker {
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--gold);
}

.muted {
    color: var(--ink-muted);
    max-width: 44rem;
}

.faint {
    color: var(--ink-faint);
    font-size: 13px;
}

.numeric,
.mono {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
}

.error {
    color: var(--danger);
}

a {
    color: var(--accent);
}

/* ---- lists: rows of stock separated by hairlines ------------------------------------ */

.decks,
.cards {
    list-style: none;
    margin: 1rem 0;
    padding: 0;
}

.decks li a {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 1rem;
    align-items: baseline;
    justify-content: space-between;
    padding: 0.85rem 1rem;
    margin-bottom: 0.5rem;
    background: var(--stock);
    border: 1px solid var(--stroke);
    border-radius: 10px;
    color: var(--ink);
    text-decoration: none;
    /* Stacked stock: a hard lower edge, no blur. */
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.55);
}

.decks li a:hover {
    background: var(--stock-raised);
    border-color: var(--stroke-strong);
}

.decks .name {
    font-family: var(--display);
    font-weight: 600;
    font-size: 16px;
}

.decks .meta,
.cards .quantity {
    color: var(--ink-muted);
    font-family: var(--mono);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

.cards li {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--stroke-faint);
}

.cards .controls {
    display: flex;
    gap: 0.5rem;
}

/* ---- forms and buttons --------------------------------------------------------------- */

.stack {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    align-items: flex-start;
    max-width: 24rem;
}

.stack label {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    width: 100%;
    color: var(--ink-muted);
    font-size: 12px;
    letter-spacing: 0.02em;
}

input,
select,
textarea {
    width: 100%;
    padding: 0.55rem 0.7rem;
    background: var(--stock);
    color: var(--ink);
    border: 1px solid var(--stroke);
    border-radius: 8px;
    font-family: var(--body);
    font-size: 14px;
}

input::placeholder {
    color: var(--ink-faint);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.button:focus-visible,
a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.button {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.95rem;
    background: var(--stock);
    color: var(--ink);
    border: 1px solid var(--stroke);
    border-radius: 8px;
    font-family: var(--body);
    font-weight: 600;
    font-size: 13px;
    text-decoration: none;
    cursor: pointer;
}

.button:hover {
    background: var(--stock-raised);
    border-color: var(--stroke-strong);
}

.button.primary {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.button.primary:hover {
    background: var(--accent-pressed);
    border-color: var(--accent-pressed);
}

.button.danger {
    border-color: var(--danger);
    color: var(--danger);
}

.button:disabled {
    color: var(--ink-disabled);
    border-color: var(--stroke-faint);
    background: var(--mat);
    cursor: default;
}

.link {
    background: none;
    border: 0;
    padding: 0;
    color: var(--ink-muted);
    font: inherit;
    cursor: pointer;
}

.link:hover {
    color: var(--ink);
}

form.inline {
    display: inline;
}

/* ---- published decks ----------------------------------------------------------------- */

/*
    A row here is two things: the deck, which is a link, and the copy, which is not. The shared
    .decks rule makes the link the whole card, so the row itself becomes the strip that holds
    both and the link keeps its own padding and hover.
*/
.decks li.published {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: stretch;
    margin-bottom: 0.5rem;
}

.decks li.published a:first-child {
    flex: 1 1 18rem;
    margin-bottom: 0;
}

.decks li.published .button {
    flex: 0 0 auto;
    align-self: center;
}

.find {
    /* Side by side where there is room: two short fields stacked read as a form to fill in. */
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-end;
    max-width: none;
}

.find label {
    width: auto;
    min-width: 12rem;
}

/* ---- sections and footer ------------------------------------------------------------- */

/* A hairline and typography, never a box inside a box. */
.section {
    margin-top: 2.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--stroke-faint);
}

footer.muted {
    margin-top: 3rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--stroke-faint);
    color: var(--ink-faint);
    font-size: 12px;
}

.switch a {
    color: var(--accent);
}

/* ---- the phone ----------------------------------------------------------------------- */

/*
    Installed from a phone browser this is a phone application, so the spine becomes a bar at
    the bottom — where a thumb is — and the brand becomes a header. The safe-area insets are
    what keep the bar clear of the home indicator on an iPhone; without them the last
    destination sits under it and cannot be pressed.
*/
@media (max-width: 860px) {
    .shell {
        grid-template-columns: minmax(0, 1fr);
    }

    .spine {
        position: fixed;
        inset: auto 0 0 0;
        z-index: 20;
        flex-direction: row;
        padding: 0;
        border-right: 0;
        border-top: 1px solid var(--stroke);
        background: var(--mat);
        padding-bottom: env(safe-area-inset-bottom);
    }

    .spine::after,
    .spine .foot {
        display: none;
    }

    .brand {
        /* Not in the bar: a wordmark in a bottom bar is a destination nobody presses. */
        position: fixed;
        inset: 0 0 auto 0;
        z-index: 20;
        flex-direction: row;
        gap: 0.6rem;
        padding: 0.6rem 1rem;
        padding-top: calc(0.6rem + env(safe-area-inset-top));
        border-bottom: 1px solid var(--stroke-faint);
        background: var(--mat);
    }

    .brand img {
        width: 30px;
        height: 30px;
    }

    .brand .wordmark {
        font-size: 14px;
        letter-spacing: 0.2em;
    }

    .brand .tagline {
        display: none;
    }

    .spine nav {
        flex: 1;
        flex-direction: row;
        justify-content: space-around;
        padding: 0.35rem 0.25rem;
        gap: 0;
    }

    .spine nav a,
    .spine nav button {
        flex-direction: column;
        gap: 2px;
        padding: 0.35rem 0.5rem;
        font-size: 10px;
        letter-spacing: 0.02em;
        /* A thumb needs a target, not a line of text. */
        min-width: 4rem;
        min-height: 44px;
        align-items: center;
        text-align: center;
    }

    .spine nav a.here {
        /* The rule moves to the top edge, because the bar is horizontal now. */
        box-shadow: inset 0 2px 0 var(--gold-rule);
    }

    /*
        Four destinations leave the bar for the More page, and More takes their place: five
        columns at 4rem clear 375 points, eight never could.
    */
    .spine nav .deep {
        display: none;
    }

    .spine nav .only-phone {
        display: flex;
    }

    main {
        /*
            Clear of both bars, and of the home indicator under the lower one — without the
            inset the last line of a page sits behind it on an iPhone.
        */
        padding: 4.6rem 1rem calc(6rem + env(safe-area-inset-bottom));
        max-width: none;
    }

    .find {
        flex-direction: column;
    }

    .find label {
        width: 100%;
    }

    .decks li.published .button {
        width: 100%;
        justify-content: center;
        min-height: 44px;
    }
}

@media (prefers-reduced-motion: reduce) {
    * {
        animation: none !important;
        transition: none !important;
    }
}

/*
    Sign out is a form, because signing out is a POST with an antiforgery token. The form would
    otherwise be a block in the middle of the rail and its button would start at the rail's
    padding rather than at the other labels' left edge — a row that looks misaligned by exactly
    the width of a relic. `display: contents` makes the button a child of the nav for layout,
    and the inset stands in for the icon it does not have.
*/
.spine nav form {
    display: contents;
}

.spine nav form button {
    /* It has an icon now, like every other row. */
    padding-left: 0.75rem;
}

@media (max-width: 860px) {
    .spine nav form button {
        /* In the bar the rows are centred columns, so the icon inset would push it off centre. */
        padding-left: 0.5rem;
    }
}

/* ---- the hero --------------------------------------------------------------------- */

/*
    The lamp, which with the brand block is one of the two places this design allows soft
    light. A wash rather than a photograph: a picture behind the text would be a game
    launcher, which the direction document names as the thing this must not be.
*/
.hero {
    padding: 2.5rem 0 2rem;
    background: radial-gradient(ellipse 60% 70% at 18% 30%, rgba(138, 108, 255, 0.16), transparent 70%);
}

.hero h1 {
    font-size: 34px;
    line-height: 1.15;
    max-width: 18ch;
    margin: 0.4rem 0 0.75rem;
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin: 1.25rem 0 1.75rem;
}

/* ---- figures ---------------------------------------------------------------------- */

.figures {
    display: flex;
    flex-wrap: wrap;
    gap: 2.25rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.figure {
    display: flex;
    flex-direction: column;
}

.figure .value {
    font-family: var(--display);
    font-size: 30px;
    line-height: 1.1;
    color: var(--gold);
}

.figure .label {
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-faint);
}

/* ---- deck tiles ------------------------------------------------------------------- */

.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 1rem;
    list-style: none;
    margin: 1.25rem 0;
    padding: 0;
}

.tile {
    position: relative;
    display: block;
    aspect-ratio: 5 / 3;
    overflow: hidden;
    border: 1px solid var(--stroke);
    border-radius: 10px;
    background: var(--stock);
    text-decoration: none;
    color: var(--ink);
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.55);
}

.tile img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.tile:hover {
    border-color: var(--gold-rule);
}

/* The gold rule at the foot, over the art, with the name on a scrim above it. */
.tile .scrim {
    position: absolute;
    inset: auto 0 0 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.7rem 0.8rem 0.6rem;
    background: linear-gradient(transparent, rgba(7, 6, 12, 0.92) 55%);
    border-bottom: 2px solid var(--gold-rule);
}

.tile .name {
    font-family: var(--display);
    font-weight: 600;
    font-size: 16px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
}

.tile .meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    font-family: var(--mono);
    font-size: 11px;
    color: var(--ink-muted);
}

.tile .star {
    color: var(--gold);
}

/* A deck with no art anywhere: the name at full size, deliberately, not a grey rectangle. */
.tile.bare .scrim {
    inset: 0;
    justify-content: center;
    background: linear-gradient(160deg, var(--stock-raised), var(--stock));
}

.tile.bare .name {
    font-size: 19px;
}

/* ---- the deck workspace ------------------------------------------------------------ */

.workspace {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 21rem;
    gap: 1.5rem;
    align-items: start;
}

.deck-head {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding-bottom: 0.9rem;
    border-bottom: 1px solid var(--stroke-faint);
}

.deck-head .title {
    font-family: var(--display);
    font-weight: 600;
    font-size: 24px;
    padding: 0.2rem 0.4rem;
    background: none;
    border: 1px solid transparent;
    border-radius: 6px;
}

.deck-head .title:hover,
.deck-head .title:focus {
    background: var(--stock);
    border-color: var(--stroke);
}

.deck-head .summary {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    color: var(--ink-muted);
    font-size: 12px;
}

.deck-head .actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    align-items: center;
    margin-top: 0.35rem;
}

.deck-head .actions select {
    width: auto;
    min-width: 9rem;
}

/* ---- zone tabs --------------------------------------------------------------------- */

.zones {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    padding: 0.8rem 0;
}

.zones .spacer {
    flex: 1;
}

.zones select {
    width: auto;
    min-width: 8.5rem;
    font-size: 12px;
    padding: 0.35rem 0.5rem;
}

.tab {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.8rem;
    background: none;
    border: 1px solid transparent;
    border-radius: 999px;
    color: var(--ink-muted);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

.tab:hover {
    color: var(--ink);
    background: var(--mat);
}

.tab.on {
    background: var(--stock);
    border-color: var(--stroke);
    color: var(--ink);
    box-shadow: inset 0 -2px 0 var(--gold-rule);
}

.tab .numeric {
    font-size: 11px;
    color: var(--ink-faint);
}

.section-head {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin: 1.4rem 0 0.6rem;
    font-size: 15px;
}

.section-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: baseline;
    justify-content: space-between;
}

.section-bar .filter {
    width: auto;
    min-width: 14rem;
}

/* ---- card stacks ------------------------------------------------------------------- */

/*
    Artwork first: the card is the picture, and the text under it is what the picture cannot
    say at this size. Selected is a fill and a gold hairline, which is the selection language
    the rest of the product uses.
*/
.stacks {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(146px, 1fr));
    gap: 0.75rem;
    list-style: none;
    margin: 0 0 1.25rem;
    padding: 0;
}

.card-stack {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.card-stack .face {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 488 / 680;
    padding: 0;
    overflow: hidden;
    background: var(--stock);
    border: 1px solid var(--stroke);
    border-radius: 9px;
    cursor: pointer;
}

.card-stack .face img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.card-stack.reading .face {
    border-color: var(--gold-rule);
    box-shadow: 0 0 0 1px var(--gold-rule);
}

.card-stack .no-art {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 0.6rem;
    text-align: center;
    background: linear-gradient(160deg, var(--stock-raised), var(--stock));
}

.card-stack .no-art .name {
    font-family: var(--display);
    font-size: 13px;
    color: var(--ink-muted);
}

/* The number of copies, as a plate in the corner rather than a badge floating on the art. */
.card-stack .count {
    position: absolute;
    right: 4px;
    bottom: 4px;
    min-width: 22px;
    padding: 1px 5px;
    background: rgba(7, 6, 12, 0.88);
    border: 1px solid var(--gold-rule);
    border-radius: 5px;
    color: var(--gold);
    font-size: 11px;
}

.card-stack .line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    font-size: 12px;
}

.card-stack .line .name {
    color: var(--ink-muted);
}

.card-stack .controls {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 12px;
}

.card-stack .controls .link {
    /* A thumb-sized target even on a mouse: these are pressed repeatedly. */
    min-width: 24px;
    min-height: 24px;
    font-size: 15px;
}

/* ---- mana pips --------------------------------------------------------------------- */

.cost {
    display: inline-flex;
    gap: 2px;
    vertical-align: middle;
}

.pip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    font-family: var(--mono);
    font-size: 9px;
    font-weight: 500;
    color: #0b0910;
    border: 1px solid rgba(0, 0, 0, 0.45);
}

.pip.w { background: #f4efdc; }
.pip.u { background: #9fd3ef; }
.pip.b { background: #b3a9b8; }
.pip.r { background: #f2a48a; }
.pip.g { background: #9ed2ad; }
.pip.c { background: #cbc7d6; }

/* ---- the rail ---------------------------------------------------------------------- */

.rail {
    position: sticky;
    top: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 1rem;
    background: var(--stock);
    border: 1px solid var(--stroke);
    border-radius: 10px;
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.55);
}

.rail h2 {
    margin: 0;
    font-size: 15px;
}

.rail .reading-name {
    font-size: 17px;
}

.rail .reading-art {
    width: 100%;
    border-radius: 8px;
    display: block;
}

.exports {
    list-style: none;
    margin: 0;
    padding: 0;
}

.exports li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.4rem 0;
    border-bottom: 1px solid var(--stroke-faint);
    font-size: 13px;
}

/* ---- statistics --------------------------------------------------------------------- */

.stats .figures {
    gap: 1.25rem;
}

.stats .figure .value {
    font-size: 22px;
}

.curve {
    display: flex;
    align-items: flex-end;
    gap: 4px;
    height: 110px;
    list-style: none;
    margin: 0.5rem 0 1rem;
    padding: 0;
}

.curve li {
    display: flex;
    flex: 1;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 2px;
    height: 100%;
}

.curve .bar {
    width: 100%;
    background: linear-gradient(var(--accent), var(--accent-pressed));
    border-radius: 3px 3px 0 0;
}

.curve .count,
.curve .mv {
    font-family: var(--mono);
    font-size: 10px;
    color: var(--ink-faint);
}

.curve .mv {
    color: var(--ink-muted);
}

.distribution {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    font-size: 13px;
}

.distribution li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.28rem 0;
    border-bottom: 1px solid var(--stroke-faint);
}

/* ---- finder and search results ------------------------------------------------------ */

.finder label {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 12px;
    color: var(--ink-muted);
}

.hits {
    list-style: none;
    margin: 0.75rem 0;
    padding: 0;
}

.hits li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--stroke-faint);
}

.hits .line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    font-size: 13px;
}

.hits .name {
    font-family: var(--display);
    font-weight: 600;
}

/* ---- sharing choices ----------------------------------------------------------------- */

.choices {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.choice {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    padding: 0.55rem 0.7rem;
    text-align: left;
    background: var(--mat);
    border: 1px solid var(--stroke-faint);
    border-radius: 8px;
    color: var(--ink-muted);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

.choice .label {
    color: var(--ink);
    font-weight: 600;
}

.choice.chosen {
    background: var(--stock-raised);
    border-color: var(--stroke-strong);
    box-shadow: inset 2px 0 0 var(--gold-rule);
}

.share-link {
    display: flex;
    gap: 0.4rem;
    align-items: center;
}

.share-link input {
    font-family: var(--mono);
    font-size: 11px;
}

.row {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* ---- narrow, for everything above ---------------------------------------------------- */

/*
    The rail moves above the cards rather than beside them, because a column of twenty-one
    rem next to a column of cards is two columns of nothing on a tablet. Order -1 puts the
    card being read at the top, where a reader who just tapped it is looking.
*/
@media (max-width: 1100px) {
    .workspace {
        grid-template-columns: minmax(0, 1fr);
    }

    .rail {
        position: static;
        order: -1;
    }
}

@media (max-width: 860px) {
    .hero {
        padding: 1.25rem 0 1rem;
    }

    .hero h1 {
        font-size: 26px;
    }

    .figures {
        gap: 1.25rem;
    }

    .tiles {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    }

    .stacks {
        grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    }

    .deck-head .actions .button,
    .zones .tab {
        min-height: 40px;
    }

    .hits li {
        flex-wrap: wrap;
    }
}

/*
    The card beside a search result.

    Cropped to the top of the frame rather than shown whole: at this height a full card is the
    art, the type line and the rules text all illegible together, and the top strip is the part
    that identifies it — the name and the illustration.
*/
.hits .thumb {
    flex: 0 0 auto;
    width: 46px;
    height: 34px;
    object-fit: cover;
    object-position: top;
    border: 1px solid var(--stroke);
    border-radius: 5px;
}

/*
    On a narrow screen the rail only exists when it has something in it.

    It is moved above the cards, because a reader who has just tapped a card is looking at the
    top of the page — but an empty rail there is a block of "Pick a card to read it here"
    between the deck's name and the deck itself.
*/
@media (max-width: 1100px) {
    .rail:not(.open) {
        display: none;
    }
}

/* ---- the collection ------------------------------------------------------------------ */

/*
    A collection is a thing you look at, so it is a wall of cards rather than a table. The
    count sits on the card as a plate, the way it does on a deck's stacks, and what the server
    could not name shows the picture alone — which is still the card.
*/
.owned {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
    gap: 0.75rem;
    list-style: none;
    margin: 1.25rem 0;
    padding: 0;
}

.owned li {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.owned img {
    width: 100%;
    aspect-ratio: 488 / 680;
    object-fit: cover;
    display: block;
    background: var(--stock);
    border: 1px solid var(--stroke);
    border-radius: 9px;
}

.owned .count {
    position: absolute;
    top: 4px;
    right: 4px;
    min-width: 22px;
    padding: 1px 5px;
    text-align: center;
    background: rgba(7, 6, 12, 0.88);
    border: 1px solid var(--gold-rule);
    border-radius: 5px;
    color: var(--gold);
    font-family: var(--mono);
    font-size: 11px;
}

.owned .under {
    display: flex;
    flex-direction: column;
    gap: 1px;
    font-size: 11px;
}

.owned .name {
    font-family: var(--display);
    font-weight: 600;
    font-size: 12px;
    color: var(--ink-muted);
}

@media (max-width: 860px) {
    .owned {
        grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
    }
}

/* ---- proxy projects ------------------------------------------------------------------ */

/*
    Proxy artwork is four-by-three rather than card-shaped: what is stored is the illustration,
    and the frame around it is drawn at print time by the installed application.
*/
.proxies {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 0.75rem;
    list-style: none;
    margin: 1rem 0;
    padding: 0;
}

.proxies li {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.proxies .face {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    padding: 0;
    overflow: hidden;
    background: var(--stock);
    border: 1px solid var(--stroke);
    border-radius: 9px;
    cursor: pointer;
}

.proxies .face img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.proxies li.chosen .face {
    border-color: var(--gold-rule);
    box-shadow: 0 0 0 1px var(--gold-rule);
}

.proxies .no-art {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 0.6rem;
    text-align: center;
    background: linear-gradient(160deg, var(--stock-raised), var(--stock));
    color: var(--ink-faint);
    font-size: 12px;
}

.proxies .under {
    display: flex;
    flex-direction: column;
    font-size: 12px;
}

.proxies .under .name {
    font-family: var(--display);
    font-weight: 600;
}

/* ---- the provider key ----------------------------------------------------------------- */

/*
    Held apart from the form below it, with its own hairline, because what it says about the
    key is the point rather than decoration around a field.
*/
.apikey {
    max-width: 34rem;
    margin: 1rem 0 1.25rem;
    padding: 0.85rem 1rem;
    background: var(--stock);
    border: 1px solid var(--stroke);
    border-left: 2px solid var(--gold-rule);
    border-radius: 8px;
}

.apikey label {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 12px;
    color: var(--ink-muted);
}

.apikey input {
    font-family: var(--mono);
}

.apikey p {
    margin: 0.6rem 0 0;
    max-width: none;
}

textarea {
    font-family: var(--body);
    resize: vertical;
}

@media (max-width: 860px) {
    .proxies {
        grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    }
}

/* ---- the More page ------------------------------------------------------------------ */
/*
    The four destinations the phone bar cannot hold, as rows rather than as a grid: each one
    is a place to go with a sentence saying what is there, and a row is what a thumb runs down.
*/

.destinations {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.destinations a,
.destinations button {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    width: 100%;
    /* A thumb needs a target, not a line of text. */
    min-height: 56px;
    padding: 0.8rem 0.9rem;
    border: 1px solid transparent;
    border-radius: 10px;
    background: none;
    font: inherit;
    color: var(--ink);
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.destinations a:hover,
.destinations button:hover {
    border-color: var(--stroke);
    background: var(--stock);
}

.destinations img {
    flex: none;
    image-rendering: pixelated;
}

.destinations .name {
    display: block;
    font-weight: 600;
}

.destinations .muted {
    display: block;
    font-size: 13px;
}

.destinations form {
    margin: 0;
}
