/* The app's design system, on the web.
 *
 * These are the pages a shared link lands on — /posts/<id>/, /challenges/<id>/,
 * /users/<username>/ — and until now they looked like a different product from the app
 * that link opens. Every value here is copied from `sailgram_flutter_v2/lib/design`
 * rather than approximated, so the two cannot drift: the colours are
 * `tokens.dart`, the radii and spacing are `Radii` and `Insets`, and the type is
 * `SailType` down to the tracking.
 *
 * Deliberately standalone, not a Bootstrap theme. Matching this palette by overriding
 * `--bs-*` would have meant fighting halfmoon's own cascade for every surface, and
 * these three pages need a column, a grid and a progress bar.
 *
 * Dark only. The app carries both themes and ships dark; a shared link is a poster,
 * and a poster has one look. */

/* --- Archivo, the app's one typeface ---------------------------------------------
 *
 * The same variable file the app bundles, with the same two axes. The width axis is
 * the reason it is the variable font and not a static instance: the display voice is
 * genuinely condensed (wdth 78), not a normal-width face squeezed by the browser. */
@font-face {
    font-family: 'Archivo';
    src: url('../fonts/Archivo.ttf') format('truetype-variations');
    font-weight: 100 900;
    font-stretch: 62% 125%;
    font-style: normal;
    font-display: swap;
}

:root {
    color-scheme: dark;

    /* tokens.dart — SailColors */
    --void: #0A0B0D;
    --surface: #15171B;
    --raised: #1E2126;
    --track: #282C33;
    --bone: #F4F1E8;
    --bone-dim: #9AA0A8;
    --bone-faint: #5C636C;
    --danger: #E5484D;

    /* Insets, a 4pt grid */
    --xs: 4px;
    --sm: 8px;
    --md: 12px;
    --lg: 16px;
    --xl: 24px;
    --xxl: 32px;

    /* Radii */
    --r-tile: 18px;
    --r-card: 24px;
    --r-hero: 28px;
    --r-pill: 999px;

    /* Motion */
    --fast: 140ms;
    --base: 260ms;
    --sail: cubic-bezier(0.215, 0.61, 0.355, 1); /* easeOutCubic */
}

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    min-height: 100vh;
    background: var(--void);
    color: var(--bone);
    font-family: 'Archivo', system-ui, sans-serif;
    font-size: 15px;
    font-variation-settings: 'wght' 400, 'wdth' 100;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

img {
    display: block;
    max-width: 100%;
}

a {
    color: inherit;
    text-decoration: none;
}

/* --- type ------------------------------------------------------------------------
 *
 * SailType, one class per style. Sizes are set per use with --size so the tracking
 * can stay proportional to it, as it is in Dart. */

.display {
    font-variation-settings: 'wght' 900, 'wdth' 78;
    font-weight: 900;
    font-size: var(--size, 34px);
    letter-spacing: calc(var(--size, 34px) * -0.012);
    line-height: 0.92;
    text-transform: uppercase;
    margin: 0;
}

.figure {
    font-variation-settings: 'wght' 900, 'wdth' 78;
    font-weight: 900;
    font-size: var(--size, 46px);
    letter-spacing: calc(var(--size, 46px) * -0.02);
    line-height: 0.95;
    font-variant-numeric: tabular-nums;
    margin: 0;
}

.kicker {
    font-variation-settings: 'wght' 800, 'wdth' 100;
    font-weight: 800;
    font-size: var(--size, 9.5px);
    letter-spacing: calc(var(--size, 9.5px) * 0.26);
    line-height: 1.2;
    text-transform: uppercase;
    color: var(--bone-dim);
    margin: 0;
}

.numeric {
    font-variation-settings: 'wght' 700, 'wdth' 100;
    font-weight: 700;
    font-size: var(--size, 12px);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.dim {
    color: var(--bone-dim);
}

.faint {
    color: var(--bone-faint);
}

/* --- layout ---------------------------------------------------------------------- */

.page {
    max-width: var(--page, 640px);
    margin: 0 auto;
    padding: 0 var(--lg) var(--xxl);
}

.bar {
    display: flex;
    align-items: center;
    gap: var(--sm);
    max-width: var(--page, 640px);
    margin: 0 auto;
    padding: var(--lg) var(--lg) var(--xl);
}

.bar__mark {
    width: 24px;
    height: 24px;
}

.stack {
    display: flex;
    flex-direction: column;
    gap: var(--lg);
}

.row {
    display: flex;
    align-items: center;
    gap: var(--sm);
}

.spread {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--md);
}

.grow {
    flex: 1;
    min-width: 0;
}

.truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- surfaces -------------------------------------------------------------------
 *
 * Depth by fill, never by border: `surface` sits on `void`, `raised` on `surface`.
 * That is the whole grammar of the app's cards. */

.card {
    background: var(--surface);
    border-radius: var(--r-card);
    padding: var(--lg);
}

.card--raised {
    background: var(--raised);
}

.card--flush {
    padding: 0;
    overflow: hidden;
}

/* --- media ----------------------------------------------------------------------- */

.media {
    position: relative;
    background: var(--raised);
    border-radius: var(--r-card);
    overflow: hidden;
    aspect-ratio: var(--ratio, 4 / 5);
}

.media__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.media--contain .media__img {
    object-fit: contain;
    background: var(--void);
}

/* The chrome over a picture, and the scrim that keeps it legible on a pale one. */
.media__head,
.media__foot {
    position: absolute;
    left: 0;
    right: 0;
    display: flex;
    align-items: center;
    gap: var(--sm);
    padding: var(--md);
}

.media__head {
    top: 0;
    background: linear-gradient(180deg, rgba(10, 11, 13, 0.72), transparent);
}

.media__foot {
    bottom: 0;
    /* Reaches further up than the head's, and with a shadow behind the type: what sits
       here is a headline over somebody's photograph, and a challenge shot on a pale
       quay is exactly the case where a gradient alone is not enough. */
    background: linear-gradient(0deg, rgba(10, 11, 13, 0.92) 0%, rgba(10, 11, 13, 0.72) 45%, transparent 100%);
    text-shadow: 0 1px 12px rgba(10, 11, 13, 0.85);
}

.media__play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    pointer-events: none;
}

.media__play span {
    display: grid;
    place-items: center;
    width: 62px;
    height: 62px;
    border-radius: var(--r-pill);
    background: rgba(10, 11, 13, 0.55);
    font-size: 30px;
    line-height: 1;
}

/* --- pills and chips ------------------------------------------------------------- */

.pill {
    display: inline-flex;
    align-items: center;
    gap: var(--xs);
    height: 34px;
    padding: 0 var(--md);
    border-radius: var(--r-pill);
    background: var(--raised);
    font-variation-settings: 'wght' 800, 'wdth' 100;
    font-weight: 800;
    font-size: 12px;
    letter-spacing: 0.01em;
    white-space: nowrap;
}

.pill--glass {
    background: rgba(10, 11, 13, 0.55);
}

.pill--solid {
    color: var(--bone);
}

.pill i,
.pill .sail-icon {
    font-size: 14px;
}

/* --- avatars --------------------------------------------------------------------- */

.avatar {
    border-radius: var(--r-pill);
    object-fit: cover;
    aspect-ratio: 1;
    background: var(--raised);
    flex: none;
}

/* --- stat tiles ------------------------------------------------------------------ */

.tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(88px, 1fr));
    gap: var(--sm);
}

.tile {
    background: var(--raised);
    border-radius: var(--r-tile);
    padding: var(--md);
    text-align: center;
}

.tile__value {
    font-variation-settings: 'wght' 900, 'wdth' 78;
    font-weight: 900;
    font-size: 26px;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.tile__label {
    margin-top: var(--xs);
}

/* --- the eight attributes -------------------------------------------------------- */

.sigils {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(124px, 1fr));
    gap: var(--sm);
}

.sigil {
    display: flex;
    align-items: center;
    gap: var(--sm);
    background: var(--raised);
    border-radius: var(--r-pill);
    padding: var(--sm) var(--md);
}

/* The attribute's own colour, from the fixture the app copies byte for byte. */
.sigil__glyph {
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border-radius: var(--r-pill);
    font-size: 15px;
    color: var(--bone);
    flex: none;
}

.sigil__name {
    font-size: 11px;
}

.sigil__value {
    margin-left: auto;
    font-variation-settings: 'wght' 900, 'wdth' 78;
    font-weight: 900;
    font-size: 16px;
    font-variant-numeric: tabular-nums;
}

.sigil--empty {
    opacity: 0.45;
}

/* --- the countdown track --------------------------------------------------------- */

.track {
    height: 6px;
    border-radius: var(--r-pill);
    background: var(--track);
    overflow: hidden;
}

.track__fill {
    height: 100%;
    border-radius: var(--r-pill);
    width: var(--fill, 0%);
}

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

.grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--xs);
}

.grid__tile {
    position: relative;
    aspect-ratio: 1;
    border-radius: var(--r-tile);
    overflow: hidden;
    background: var(--raised);
    transition: transform var(--fast) var(--sail);
}

.grid__tile:hover {
    transform: scale(1.02);
}

.grid__tile img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.grid__badge {
    position: absolute;
    top: var(--sm);
    right: var(--sm);
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: var(--r-pill);
    background: rgba(10, 11, 13, 0.6);
    font-size: 12px;
}

/* --- the standings --------------------------------------------------------------- */

.standing {
    display: flex;
    align-items: center;
    gap: var(--md);
    padding: var(--sm) 0;
}

.standing + .standing {
    border-top: 1px solid var(--track);
}

.standing__rank {
    width: 22px;
    text-align: center;
    font-variation-settings: 'wght' 900, 'wdth' 78;
    font-weight: 900;
    font-size: 15px;
    color: var(--bone-faint);
    font-variant-numeric: tabular-nums;
    flex: none;
}

.standing__score {
    margin-left: auto;
    font-variation-settings: 'wght' 900, 'wdth' 78;
    font-weight: 900;
    font-size: 18px;
    font-variant-numeric: tabular-nums;
}

/* --- the landing ------------------------------------------------------------------
 *
 * The one page nobody arrives at from a link, so it has nothing to be second to: it
 * takes the height it can get and centres in it. The glow is the same grammar as the
 * cards — `surface` blooming out of `void`, no border anywhere — and is fixed rather
 * than absolute so it cannot add a scrollbar of its own. */

/* The landing page has no length of its own, so it takes the screen and pushes the
   footer to the bottom of it — rather than leaving it stranded halfway down, which is
   what a plain `min-height` on the hero does. */
.landing {
    min-height: 100vh;
    /* `vh` on a phone is the viewport *without* the retracting address bar, so a 100vh
       column starts life taller than what you can see and the footer sits under the
       fold. `dvh` is the height there actually is; the `vh` above it is the fallback. */
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
}

.landing .hero {
    flex: 1;
}

.hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: var(--xxl) var(--lg) var(--xl);
}

.hero__glow {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background: radial-gradient(58% 42% at 50% 30%, var(--surface) 0%, transparent 72%);
}

.hero__mark {
    width: 128px;
    margin-bottom: var(--lg);
}

/* The wordmark carries the page, so it is allowed to run to the edges of a phone and
   grow with the viewport instead of picking one size for both. */
.hero__word {
    --size: clamp(52px, 17vw, 92px);
}

.hero__lead {
    margin: var(--md) 0 0;
    max-width: 30ch;
    color: var(--bone-dim);
    font-size: 17px;
}

.hero__store {
    display: inline-block;
    margin-top: var(--xl);
    transition: transform var(--fast) var(--sail);
}

.hero__store:hover {
    transform: translateY(-2px);
}

.hero__store img {
    width: 168px;
}

/* --- the way into the app -------------------------------------------------------- */

.cta {
    display: flex;
    align-items: center;
    gap: var(--lg);
    background: var(--surface);
    border-radius: var(--r-card);
    padding: var(--lg);
}

.cta img {
    width: 148px;
    flex: none;
}

.foot {
    max-width: var(--page, 640px);
    margin: 0 auto;
    padding: var(--xl) var(--lg) var(--xxl);
    display: flex;
    gap: var(--lg);
    justify-content: center;
}

/* A link that behaves like a link, without looking like 1996. */
.foot a:hover,
.bar a:hover {
    color: var(--bone);
}

@media (max-width: 480px) {
    .cta {
        flex-direction: column;
        align-items: flex-start;
    }
}
