/* ==========================================================================
   Hologramu — site styles

   The site is dressed as the app. Open Hologramu and you get a deep blue
   night, a cyan wireframe floor running to the horizon and one magenta wash
   in the corner; everything on top of that is a flat panel with a hairline
   around it. This stylesheet uses the same three moves and nothing else.

   Rules that keep it from drifting back into template-land:
     - Headlines are one solid colour. No gradient-filled text.
     - Buttons are rectangles with a 1px edge and two cut corners, like the
       app's own hologram frames (see "Hologram frames" at the end). No pill
       shapes, no rainbow fills, no lift-on-hover.
     - Depth comes from the grid and from flat panels sitting on it, not from
       blurred blobs floating behind the content.
     - Uppercase mono is a system for labels — spec band, captions, tags — and
       is never used for body copy or buttons.
   ========================================================================== */

/* ============================ Type ============================ */

/* Self-hosted, subsetted to Latin (see assets/fonts/). The privacy page
   promises that every font comes off our own server, so there is no CDN and
   no Google Fonts call here — and there must never be one. */
@font-face {
    font-family: "Geist";
    src: url("../fonts/Geist-subset.woff2") format("woff2-variations");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Geist Mono";
    src: url("../fonts/GeistMono-subset.woff2") format("woff2-variations");
    font-weight: 100 900;
    font-style: normal;
    font-display: swap;
}

:root {
    /* ---- Ink. The app's night: navy, never violet. ---- */
    --ink-900: #050A12;
    --ink-800: #08111E;
    --ink-700: #0C1727;
    --ink-600: #122036;

    /* ---- Light. Straight off the editor's accents. ---- */
    --cyan: #4CDDFF;
    --cyan-soft: #8AEAFF;
    --pink: #FF73C4;

    /* Kept because docs.css and the legal pages still name it. It is now a
       muted steel blue rather than lavender — a third tone that recedes. */
    --lavender: #9FC4E4;

    --head: #EAF4FF;
    --text: #B4C7DD;
    --mute: #7B90AB;

    --line: rgba(120, 195, 240, 0.14);
    --line-strong: rgba(120, 195, 240, 0.26);
    --line-cyan: rgba(76, 221, 255, 0.38);

    /* Panels are flat fills, not gradients — the app draws them the same way. */
    --panel: rgba(12, 23, 39, 0.72);
    --panel-hi: rgba(18, 32, 54, 0.88);

    --font: "Geist", "Segoe UI", "Noto Sans", "Noto Sans JP", "Hiragino Sans", system-ui, sans-serif;
    --mono: "Geist Mono", ui-monospace, "Cascadia Mono", Menlo, monospace;

    /* A short radius scale. 999px exists only for genuine tags. */
    --r-sm: 4px;
    --r: 8px;
    --r-lg: 12px;

    --shadow: 0 24px 60px -30px rgba(0, 0, 0, 0.85);

    /* ---- Aliases kept for docs.css and the legal pages ---- */
    --bg-0: var(--ink-900);
    --bg-1: var(--ink-800);
    --white: var(--head);
    --text-dim: var(--mute);
    --hairline: var(--line);
    --surface: var(--panel);
    --surface-hi: var(--panel-hi);
    --radius: var(--r-lg);
}

* { box-sizing: border-box; }

html {
    scroll-behavior: smooth;
    /* Anything scrolled to clears the sticky header. */
    scroll-padding-top: 84px;
}

body {
    margin: 0;
    background: var(--ink-900);
    color: var(--text);
    font-family: var(--font);
    font-size: 16px;
    line-height: 1.65;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

/* The wireframe floor, straight out of the app's own backdrop. It is a real
   grid rather than a blurred glow: it gives the page a horizon and a sense of
   scale, and it is the one texture the whole site is built on.

   Masked so it is strongest at the top and gone by the footer — the same way
   the grid in the app fades into the dark. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -2;
    pointer-events: none;
    background-image:
        linear-gradient(to right, rgba(76, 221, 255, 0.055) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(76, 221, 255, 0.055) 1px, transparent 1px);
    background-size: 72px 72px;
    -webkit-mask-image: radial-gradient(ellipse 110% 75% at 50% 0%, #000 15%, transparent 72%);
    mask-image: radial-gradient(ellipse 110% 75% at 50% 0%, #000 15%, transparent 72%);
}

/* One magenta wash in the upper corner — the app has exactly this, and exactly
   one of it. Wide and weak enough to read as tinted air, not as a glowing ball. */
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(ellipse 60% 45% at 88% -8%, rgba(255, 115, 196, 0.10), transparent 70%),
        radial-gradient(ellipse 70% 40% at 8% 2%, rgba(76, 221, 255, 0.07), transparent 70%);
}

a { color: var(--cyan); text-decoration: none; }
img, video { max-width: 100%; display: block; }

h1, h2, h3, h4 {
    color: var(--head);
    line-height: 1.12;
    letter-spacing: -0.021em;
    font-weight: 600;
    margin: 0 0 0.5em;
    text-wrap: balance;
}

p { text-wrap: pretty; }

::selection {
    background: rgba(76, 221, 255, 0.28);
    color: var(--head);
}

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

.container {
    width: 100%;
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 28px;
}

.skip-link {
    position: absolute;
    left: 12px;
    top: -60px;
    z-index: 200;
    padding: 10px 18px;
    border: 1px solid var(--line-cyan);
    border-top: 0;
    border-radius: 0 0 var(--r) var(--r);
    background: var(--ink-800);
    color: var(--head);
    transition: top 0.18s ease;
}

.skip-link:focus { top: 0; }

/* ============================ Header ============================ */

/* Sticky and opaque by default, which is what the docs and the legal pages
   want: the bar takes its 72px out of the flow and nothing ends up underneath
   it. */
.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: rgba(5, 10, 18, 0.82);
    backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line);
    transition: background 0.25s ease, border-color 0.25s ease, backdrop-filter 0.25s ease;
}

/* On the home page it lifts out of the flow instead and rides transparently
   over the hero clip, taking on its surface once the page scrolls past it —
   main.js sets .is-stuck. */
body.has-hero .site-header {
    position: fixed;
    left: 0;
    right: 0;
    background: transparent;
    backdrop-filter: none;
    border-bottom-color: transparent;
}

body.has-hero .site-header.is-stuck {
    background: rgba(5, 10, 18, 0.82);
    backdrop-filter: blur(14px);
    border-bottom-color: var(--line);
}

.site-header .container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    height: 72px;
}

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.02rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--head);
}

.brand img { width: 26px; height: 26px; }

.main-nav {
    display: flex;
    align-items: center;
    gap: 4px;
}

.main-nav a {
    padding: 7px 11px;
    border-radius: var(--r-sm);
    color: var(--mute);
    font-size: 0.9rem;
    font-weight: 500;
    transition: color 0.16s ease, background 0.16s ease;
}

.main-nav a:hover {
    color: var(--head);
    background: rgba(120, 195, 240, 0.07);
}

/* ---- Language picker ---- */

.lang-switch {
    position: relative;
    margin-left: 8px;
    padding-left: 12px;
    border-left: 1px solid var(--line);
}

.lang-btn {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 6px 9px;
    background: none;
    border: 0;
    border-radius: var(--r-sm);
    color: var(--mute);
    font: inherit;
    cursor: pointer;
    transition: color 0.16s ease, background 0.16s ease;
}

.lang-btn:hover,
.lang-btn[aria-expanded="true"] {
    color: var(--head);
    background: rgba(120, 195, 240, 0.08);
}

.lang-icon { width: 19px; height: 19px; flex: none; }

.lang-code {
    font-family: var(--mono);
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.08em;
}

.lang-menu {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 10;
    min-width: 172px;
    margin: 0;
    padding: 5px;
    list-style: none;
    border: 1px solid var(--line-strong);
    border-radius: var(--r);
    background: var(--ink-800);
    box-shadow: var(--shadow);
}

.lang-menu[hidden] { display: none; }

.lang-menu a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 8px 10px;
    border-radius: var(--r-sm);
    font-size: 0.9rem;
    color: var(--text);
    white-space: nowrap;
    transition: color 0.16s ease, background 0.16s ease;
}

.lang-menu a:hover,
.lang-menu a:focus-visible {
    color: var(--head);
    background: rgba(120, 195, 240, 0.09);
}

.lang-menu a.active { color: var(--cyan); }

.lang-menu-code {
    font-family: var(--mono);
    font-size: 0.68rem;
    letter-spacing: 0.08em;
    color: var(--mute);
}

.nav-toggle {
    display: none;
    width: 38px;
    height: 38px;
    padding: 0;
    background: rgba(12, 23, 39, 0.6);
    border: 1px solid var(--line);
    border-radius: var(--r-sm);
    color: var(--head);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}

/* ============================ Buttons ============================ */

/* Modelled on the app's own: a rectangle with a 1px edge and a flat fill.
   Deliberately not a gradient pill, and deliberately not animated upward on
   hover — only the fill changes. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    padding: 12px 22px;
    border: 1px solid var(--cyan);
    border-radius: var(--r-sm);
    background: var(--cyan);
    color: #041019;
    font-family: inherit;
    font-size: 0.94rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    text-align: center;
    cursor: pointer;
    transition: background 0.16s ease, border-color 0.16s ease, color 0.16s ease;
}

.btn:hover {
    background: var(--cyan-soft);
    border-color: var(--cyan-soft);
}

.btn-ghost {
    background: rgba(12, 23, 39, 0.55);
    border-color: var(--line-strong);
    color: var(--head);
    backdrop-filter: blur(4px);
}

.btn-ghost:hover {
    background: rgba(76, 221, 255, 0.10);
    border-color: var(--line-cyan);
    color: var(--head);
}

.btn-block { display: flex; width: 100%; }

.btn[aria-disabled="true"],
.btn.is-disabled {
    pointer-events: none;
    background: transparent;
    border-color: var(--line);
    color: var(--mute);
    backdrop-filter: none;
}

/* ============================ Hero ============================ */

.hero {
    position: relative;
    display: flex;
    align-items: center;
    text-align: center;
    min-height: 100vh;
    min-height: 100svh;
    padding: 120px 0 96px;
    overflow: hidden;
    /* The video is its own backdrop — the page grid would only fight it. */
    isolation: isolate;
}

.hero-media {
    position: absolute;
    inset: 0;
    z-index: -2;
    background: var(--ink-900);
}

/* The clip is cropped to the app's viewport — the avatar on its grid, with no
   panels or debug overlay in shot. Centred behind the centred headline: the
   scrim is darkest in the middle, so the avatar reads through it as a silhouette
   rather than fighting the words. */
.hero-media video,
.hero-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 34% center;
}

/* Two scrims stacked. The vertical one keeps the header legible at the top and
   melts the clip into the page at the bottom; the horizontal one darkens the
   left so the headline has something to sit on while the right half of the
   footage stays visible. */
.hero-scrim {
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        /* Even wash: the words sit in the middle now, so there is no one side
           to protect — the whole clip has to come down instead. */
        linear-gradient(rgba(5, 10, 18, 0.60), rgba(5, 10, 18, 0.60)),
        /* Vignette. Load-bearing: the tracking-preview window in the corner of
           the shot is the brightest thing in the footage, and without this it
           reads as a grey box competing with the headline. */
        radial-gradient(ellipse 72% 78% at 50% 50%,
            transparent 24%,
            rgba(5, 10, 18, 0.88) 100%),
        /* Top for the header, bottom to melt the clip into the page. */
        linear-gradient(to bottom,
            rgba(5, 10, 18, 0.70) 0%,
            rgba(5, 10, 18, 0) 24%,
            rgba(5, 10, 18, 0) 56%,
            var(--ink-900) 100%);
}

.hero .container {
    position: relative;
    width: 100%;
}

.hero-inner {
    max-width: 720px;
    margin: 0 auto;
}

/* The wordmark, given the same treatment it has on the app's own start screen:
   solid light type with a tight cyan halo. Tight, not a neon sign. */
.hero h1 {
    margin: 0 0 0.22em;
    font-size: clamp(3.2rem, 9vw, 6rem);
    font-weight: 600;
    letter-spacing: -0.045em;
    line-height: 0.95;
    color: var(--head);
    text-shadow:
        0 0 26px rgba(76, 221, 255, 0.34),
        0 0 70px rgba(76, 221, 255, 0.14);
}

.hero-slogan {
    margin: 0 0 0.7em;
    font-size: clamp(1.3rem, 3vw, 1.85rem);
    font-weight: 500;
    line-height: 1.25;
    letter-spacing: -0.02em;
    color: var(--head);
}

.hero .subtitle {
    max-width: 52ch;
    margin: 0 auto;
    font-size: 1.03rem;
    color: var(--text);
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin-top: 32px;
}

.hero-note {
    margin: 16px 0 0;
    font-family: var(--mono);
    font-size: 0.76rem;
    letter-spacing: 0.02em;
    color: var(--mute);
}

/* Centred under the stack, pointing at the first row of screenshots. */
.hero-scroll {
    position: absolute;
    left: 50%;
    bottom: 30px;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    font-family: var(--mono);
    font-size: 0.66rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--mute);
}

.hero-scroll::after {
    content: "";
    width: 1px;
    height: 34px;
    background: linear-gradient(to bottom, var(--line-strong), transparent);
}

/* ============================ Spec band ============================ */

/* Replaces the old row of rounded pills: one hairline-bounded band of plain
   facts, set in mono so it reads as a spec sheet rather than as marketing. */
.specs {
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    background: rgba(8, 17, 30, 0.5);
}

.specs ul {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.specs li {
    flex: 1 1 auto;
    padding: 18px 26px;
    font-family: var(--mono);
    font-size: 0.78rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mute);
    white-space: nowrap;
}

.specs li + li { border-left: 1px solid var(--line); }
.specs strong { color: var(--cyan); font-weight: 500; }

/* ============================ Sections ============================ */

.section { padding: 104px 0; }
.section-tight { padding: 78px 0; }

/* The showcase opens the page directly under the spec band and wants to start
   close to it — a full section's worth of air there would push the first
   screenshot off the fold. */
#showcase { padding-top: 68px; }
#showcase .section-header { margin-bottom: 40px; }

.section-alt {
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    background: rgba(8, 17, 30, 0.45);
}

/* Left-aligned, with the lede held to a readable measure beside it — a
   centred stack of title-over-subtitle is the shape every template uses.

   The rule above the heading does the job a mono eyebrow would, without
   printing the section's own name twice in a row. */
.section-header {
    max-width: 720px;
    margin: 0 0 56px;
}

.section-header::before {
    content: "";
    display: block;
    width: 44px;
    height: 2px;
    margin-bottom: 22px;
    background: var(--cyan);
}

/* For a heading that is followed by its own lede rather than by the section
   body — the about block sets its lede in a larger face of its own. */
.section-header--tight { margin-bottom: 24px; }
.section-header--tight h2 { margin-bottom: 0; }

.section-header h2 {
    font-size: clamp(1.9rem, 3.6vw, 2.6rem);
    margin-bottom: 0.35em;
}

.section-header p {
    margin: 0;
    max-width: 62ch;
    font-size: 1.02rem;
    color: var(--text);
}

/* ============================ About ============================ */

/* Deliberately the quietest block on the page. It used to open the site with a
   big heading and a screenshot beside it, which spent the most valuable space
   on the page explaining rather than showing. It is now a low band near the
   FAQ: same words, a quarter of the height. */
.about-band {
    display: grid;
    grid-template-columns: 0.72fr 1.28fr;
    gap: 40px 52px;
    align-items: start;
}

.about-intro h2 {
    font-size: 1.35rem;
    margin-bottom: 0.5em;
}

.about-intro p {
    margin: 0;
    font-size: 0.97rem;
    color: var(--text);
}

/* Three short columns rather than three stacked blocks — the whole point is
   that this reads quickly. */
.about-cols {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 28px;
}

.about-col {
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.about-col h3 {
    font-size: 0.94rem;
    margin-bottom: 0.5em;
}

.about-col p {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.6;
    color: var(--mute);
}

/* ============================ Spotlights ============================ */

/* The handful of features worth showing rather than listing. Text one side,
   the app the other, sides swapping each row. */
.spotlights {
    display: grid;
    gap: 72px;
}

.spotlight {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: 64px;
    align-items: center;
}

/* Every second row puts the media first. Done with an explicit class rather
   than :nth-child so the order survives a row being added or moved.

   The widths have to swap with it: `order` only decides which cell an item
   lands in, so leaving the template alone would squeeze every flipped
   screenshot into the narrow column. */
.spotlight--flip {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
}

.spotlight--flip .spotlight-media { order: -1; }

.spotlight-body { max-width: 46ch; }

/* The row's number. Big, mono, quiet — an index, not a badge. */
.spot-index {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0 0 20px;
    font-family: var(--mono);
    font-size: 0.78rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    color: var(--cyan);
}

.spot-index::after {
    content: "";
    width: 56px;
    height: 1px;
    background: linear-gradient(to right, var(--line-cyan), transparent);
}

.spotlight h3 {
    font-size: clamp(1.6rem, 2.8vw, 2.1rem);
    margin-bottom: 0.45em;
}

.spotlight p {
    margin: 0;
    font-size: 1.02rem;
    color: var(--text);
}

/* A flat frame around the screenshot, matching how the app frames its own
   panels: hairline, small radius, no glow. */
.spotlight-media {
    position: relative;
    margin: 0;
}

.media-frame {
    display: block;
    width: 100%;
    padding: 0;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-lg);
    background: var(--ink-800);
    overflow: hidden;
    cursor: zoom-in;
    color: inherit;
    font: inherit;
    box-shadow: var(--shadow);
    transition: border-color 0.18s ease;
}

.media-frame:hover { border-color: var(--line-cyan); }

.media-frame img,
.media-frame video {
    width: 100%;
    height: auto;
    display: block;
}

/* Quiet until pointed at, so a row reads as a picture and not as a control. */
.media-zoom {
    position: absolute;
    top: 12px;
    right: 12px;
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    color: var(--head);
    background: rgba(5, 10, 18, 0.72);
    opacity: 0;
    transition: opacity 0.16s ease;
    pointer-events: none;
}

.media-zoom svg { width: 15px; height: 15px; }

.media-frame:hover .media-zoom,
.media-frame:focus-visible .media-zoom { opacity: 1; }

.media-caption {
    margin: 12px 2px 0;
    font-family: var(--mono);
    font-size: 0.72rem;
    letter-spacing: 0.05em;
    color: var(--mute);
}

/* An empty slot should read as reserved, not as a broken image. */
.media-empty {
    display: grid;
    place-items: center;
    aspect-ratio: 16 / 9;
    background:
        linear-gradient(to right, rgba(76, 221, 255, 0.05) 1px, transparent 1px) 0 0 / 36px 36px,
        linear-gradient(to bottom, rgba(76, 221, 255, 0.05) 1px, transparent 1px) 0 0 / 36px 36px,
        var(--ink-800);
}

.media-soon {
    padding: 5px 12px;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-family: var(--mono);
    font-size: 0.68rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mute);
    background: rgba(5, 10, 18, 0.7);
}

/* A row of further views, closing out the showcase. Uniform tiles on a fixed
   ratio, so a wide settings rack and a tall panel still line up; the frames
   above keep their own proportions because they are the ones being looked at. */
.showcase-strip {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
    margin-top: 64px;
    padding-top: 44px;
    border-top: 1px solid var(--line);
}

.strip-item { margin: 0; }

.strip-item .media-frame img,
.strip-item .media-frame video {
    aspect-ratio: 16 / 10;
    object-fit: cover;
}

.strip-item .media-caption {
    font-family: var(--font);
    font-size: 0.88rem;
    letter-spacing: 0;
    color: var(--text);
}

/* ============================ Feature list ============================ */

/* Everything that did not earn a spotlight. Deliberately not twelve identical
   glowing cards: a hairline-ruled list, icon small and inline with the title,
   so it reads as an index of what else is in the box. */
.feature-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(288px, 1fr));
    gap: 0 48px;
}

.feature-card {
    padding: 26px 0;
    border-top: 1px solid var(--line);
}

.feature-head {
    display: flex;
    align-items: center;
    gap: 11px;
    margin-bottom: 10px;
}

.feature-card img {
    width: 20px;
    height: 20px;
    flex: none;
}

.feature-card h3 {
    margin: 0;
    font-size: 1rem;
    letter-spacing: -0.01em;
}

.feature-card p {
    margin: 0;
    font-size: 0.93rem;
    color: var(--mute);
}

/* ============================ Platforms ============================ */

.platform-row {
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    gap: 20px;
    align-items: stretch;
}

.platform-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 30px 28px;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--panel);
}

/* Linux is the platform, not one of two equals — it gets the cyan edge and
   the room. */
.platform-card.primary {
    padding: 38px 34px;
    border-color: var(--line-cyan);
    background: var(--panel-hi);
}

.platform-card .os-icon {
    width: 30px;
    height: 30px;
    margin-bottom: 16px;
}

.platform-card.primary .os-icon {
    width: 46px;
    height: 46px;
    margin-bottom: 20px;
}

.platform-card h3 { font-size: 1.02rem; margin-bottom: 0.35em; }
.platform-card.primary h3 { font-size: 1.7rem; margin-bottom: 0.25em; }
.platform-card.primary > p { font-size: 0.98rem; color: var(--text); }
.platform-card p { margin: 0; font-size: 0.92rem; color: var(--mute); }

.platform-versions {
    list-style: none;
    margin: 20px 0 0;
    padding: 18px 0 0;
    border-top: 1px solid var(--line);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.platform-versions li {
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: var(--mono);
    font-size: 0.8rem;
    letter-spacing: 0.01em;
    color: var(--mute);
}

.platform-card.primary .platform-versions li { font-size: 0.84rem; }

/* Tested distros get a filled marker and brighter type; untested a hollow one. */
.platform-versions li::before {
    content: "";
    width: 5px;
    height: 5px;
    flex: none;
    border: 1px solid var(--mute);
}

.platform-versions li.tested { color: var(--text); }

.platform-versions li.tested::before {
    background: var(--cyan);
    border-color: var(--cyan);
}

.platform-tag {
    position: absolute;
    top: 22px;
    right: 22px;
    padding: 4px 10px;
    border: 1px solid var(--line-cyan);
    border-radius: var(--r-sm);
    font-family: var(--mono);
    font-size: 0.66rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--cyan);
    background: rgba(76, 221, 255, 0.08);
}

/* ============================ Pricing ============================ */

.pricing-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 20px;
    align-items: stretch;
}

.pricing-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 32px 28px;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--panel);
}

.pricing-card .pricing-features { flex: 1 0 auto; }

/* Marked by a cyan rule across the top rather than a glow and a floating
   ribbon — the tier is recommended, not on sale. */
.pricing-card.featured {
    border-color: var(--line-cyan);
    background: var(--panel-hi);
}

.pricing-card.featured::before {
    content: "";
    position: absolute;
    top: -1px;
    left: -1px;
    right: -1px;
    height: 2px;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    background: var(--cyan);
}

.pricing-card.later { opacity: 0.72; }

.pricing-badge {
    position: absolute;
    top: 26px;
    right: 26px;
    font-family: var(--mono);
    font-size: 0.66rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--cyan);
}

.pricing-card h3 {
    font-size: 1.05rem;
    font-weight: 500;
    margin-bottom: 0.6em;
    color: var(--mute);
}

.price {
    font-size: 2.2rem;
    font-weight: 600;
    letter-spacing: -0.035em;
    line-height: 1.1;
    color: var(--head);
    margin-bottom: 6px;
}

.price-sub {
    font-family: var(--mono);
    font-size: 0.74rem;
    letter-spacing: 0.03em;
    color: var(--mute);
    margin-bottom: 26px;
}

.pricing-features {
    list-style: none;
    padding: 0;
    margin: 0 0 26px;
}

.pricing-features li {
    position: relative;
    padding: 8px 0 8px 22px;
    font-size: 0.92rem;
    color: var(--mute);
}

/* A check for what is included, a dash for what is only coming. */
.pricing-features li::before {
    content: "–";
    position: absolute;
    left: 2px;
    top: 8px;
    color: var(--mute);
}

.pricing-features li.on { color: var(--text); }

.pricing-features li.on::before {
    content: "";
    left: 3px;
    top: 15px;
    width: 9px;
    height: 5px;
    border-left: 1.5px solid var(--cyan);
    border-bottom: 1.5px solid var(--cyan);
    transform: rotate(-45deg);
}

.pricing-note {
    max-width: 66ch;
    margin: 38px 0 0;
    font-size: 0.94rem;
    color: var(--mute);
}

/* ============================ Callout ============================ */

.callout {
    display: grid;
    grid-template-columns: 0.8fr 1.2fr;
    gap: 20px 56px;
    padding: 46px 44px;
    border: 1px solid var(--line);
    border-left: 2px solid var(--cyan);
    border-radius: var(--r-lg);
    background: var(--panel);
}

.callout h2 {
    margin: 0;
    font-size: clamp(1.5rem, 2.6vw, 1.9rem);
}

.callout-body { grid-column: 2; }

.callout p {
    margin: 0;
    color: var(--text);
}

.callout p + p { margin-top: 14px; }

/* ============================ FAQ ============================ */

.faq-layout {
    display: grid;
    grid-template-columns: 0.6fr 1.4fr;
    gap: 64px;
    align-items: start;
}

.faq-layout .section-header { margin-bottom: 0; }

.faq-item { border-bottom: 1px solid var(--line); }
.faq-item:first-child { border-top: 1px solid var(--line); }

.faq-item summary {
    position: relative;
    padding: 20px 40px 20px 0;
    font-size: 1rem;
    font-weight: 500;
    color: var(--head);
    cursor: pointer;
    list-style: none;
    transition: color 0.16s ease;
}

.faq-item summary:hover { color: var(--cyan); }
.faq-item summary::-webkit-details-marker { display: none; }

/* A plus drawn from two rules, so the open state can just drop one of them. */
.faq-item summary::after,
.faq-item summary::before {
    content: "";
    position: absolute;
    right: 6px;
    top: 50%;
    background: var(--cyan);
    transition: opacity 0.18s ease;
}

.faq-item summary::before {
    width: 11px;
    height: 1px;
    margin-top: -0.5px;
}

.faq-item summary::after {
    width: 1px;
    height: 11px;
    margin-top: -5.5px;
    right: 11px;
}

.faq-item[open] summary::after { opacity: 0; }

.faq-item p {
    margin: 0 0 22px;
    padding-right: 40px;
    font-size: 0.96rem;
    color: var(--mute);
}

/* ============================ Lightbox ============================ */

.lightbox {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: grid;
    place-items: center;
    padding: clamp(16px, 4vw, 48px);
}

.lightbox[hidden] { display: none; }

.lightbox-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(3, 7, 13, 0.9);
    backdrop-filter: blur(8px);
    cursor: zoom-out;
}

.lightbox-dialog {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    max-width: min(1400px, 100%);
    max-height: 100%;
    animation: lightbox-in 0.16s ease-out;
}

.lightbox-stage { display: flex; min-height: 0; }

.lightbox-stage img,
.lightbox-stage video {
    display: block;
    max-width: 100%;
    max-height: calc(100vh - 170px);
    width: auto;
    height: auto;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-lg);
}

.lightbox-caption {
    margin: 0;
    max-width: 70ch;
    text-align: center;
    font-size: 0.88rem;
    color: var(--mute);
}

.lightbox-close {
    position: absolute;
    top: -48px;
    right: 0;
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    padding: 0;
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    color: var(--head);
    background: rgba(12, 23, 39, 0.8);
    cursor: pointer;
    transition: background 0.16s ease, border-color 0.16s ease;
}

.lightbox-close:hover {
    background: rgba(76, 221, 255, 0.12);
    border-color: var(--line-cyan);
}

.lightbox-close svg { width: 17px; height: 17px; }

@keyframes lightbox-in {
    from { opacity: 0; transform: scale(0.99); }
    to   { opacity: 1; transform: none; }
}

body.lightbox-open { overflow: hidden; }

/* ============================ Footer ============================ */

.site-footer {
    padding: 72px 0 30px;
    border-top: 1px solid var(--line);
    background: rgba(8, 17, 30, 0.5);
}

.footer-grid {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    gap: 44px;
    margin-bottom: 48px;
}

.footer-grid > div > p {
    margin: 14px 0 0;
    max-width: 34ch;
    font-size: 0.9rem;
    color: var(--mute);
}

.footer-translated {
    font-size: 0.82rem !important;
    color: var(--mute);
    opacity: 0.8;
}

.footer-col h4 {
    margin: 0 0 14px;
    font-family: var(--mono);
    font-size: 0.7rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--mute);
}

.footer-col ul { list-style: none; padding: 0; margin: 0; }
.footer-col li { margin-bottom: 9px; }

.footer-col a {
    font-size: 0.92rem;
    color: var(--text);
    transition: color 0.16s ease;
}

.footer-col a:hover { color: var(--cyan); }

.footer-bottom {
    padding-top: 26px;
    border-top: 1px solid var(--line);
    font-family: var(--mono);
    font-size: 0.74rem;
    letter-spacing: 0.03em;
    color: var(--mute);
}

/* ============================ Legal pages ============================ */

/* imprint.php and privacy.php: a title band over one long card of prose. The
   header is sticky (not fixed) here, so these need no clearance of their own. */
.page-header {
    padding: 64px 0 40px;
    border-bottom: 1px solid var(--line);
}

.page-header h1 {
    max-width: 20ch;
    font-size: clamp(2rem, 4vw, 2.8rem);
    margin-bottom: 0.3em;
}

.page-header p {
    margin: 0;
    max-width: 60ch;
    color: var(--mute);
}

.content-page { padding: 56px 0 96px; }

.content-card {
    max-width: 760px;
    padding: 40px 42px;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--panel);
}

.content-card > :first-child { margin-top: 0; }

.content-card h2 {
    margin: 40px 0 0.5em;
    padding-top: 26px;
    border-top: 1px solid var(--line);
    font-size: 1.15rem;
}

.content-card > h2:first-of-type {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

.content-card p {
    margin: 0 0 1.1em;
    color: var(--text);
    font-size: 0.97rem;
}

.content-card a {
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
}

.content-card a:hover { color: var(--cyan-soft); }

/* ============================ Spotlight extras ============================ */

/* A paid edition, named next to the row number — small, mono, pink, so it
   reads as a label on the row rather than as a price tag. */
.spot-tag {
    order: 2;
    padding: 2px 8px;
    border: 1px solid rgba(255, 115, 196, 0.5);
    font-size: 0.66rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--pink);
}

/* The practical line under a row's pitch: which programs, which platform. */
.spotlight p.spot-note {
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
    font-size: 0.88rem;
    color: var(--mute);
}

.section-more {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 40px;
}

/* ============================ All features (features.php) ============================ */

/* One band per area: its name and a line of context on the left, a ruled
   list of what is in it on the right — the about band's layout, repeated. */
.fl-page { padding: 24px 0 96px; }

.fl-group {
    display: grid;
    grid-template-columns: 0.62fr 1.38fr;
    gap: 28px 52px;
    padding: 48px 0;
    border-bottom: 1px solid var(--line);
}

.fl-group:last-child { border-bottom: 0; }

.fl-head h2 {
    font-size: 1.35rem;
    margin-bottom: 0.45em;
}

.fl-head p {
    margin: 0;
    font-size: 0.93rem;
    color: var(--mute);
}

.fl-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 36px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.fl-item {
    padding: 18px 0;
    border-top: 1px solid var(--line);
}

.fl-item h3 {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 6px;
    font-size: 0.98rem;
    letter-spacing: -0.01em;
}

.fl-item p {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.6;
    color: var(--mute);
}

.fl-tag {
    padding: 1px 7px;
    border: 1px solid var(--line-cyan);
    font-family: var(--mono);
    font-size: 0.62rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--cyan);
}

.fl-tag--paid {
    border-color: rgba(255, 115, 196, 0.5);
    color: var(--pink);
}

.fl-note {
    max-width: 760px;
    margin: 48px 0 0;
    color: var(--mute);
    font-size: 0.93rem;
}

@media (max-width: 900px) {
    .fl-group { grid-template-columns: 1fr; padding: 36px 0; }
}

@media (max-width: 620px) {
    .fl-list { grid-template-columns: 1fr; }
}

/* ============================ Responsive ============================ */

@media (max-width: 1040px) {
    .about-band { grid-template-columns: 1fr; gap: 30px; }
    .faq-layout { grid-template-columns: 1fr; gap: 36px; }
    .spotlight { gap: 44px; }
}

@media (max-width: 900px) {
    .main-nav { gap: 2px; }
    .main-nav a { padding: 7px 8px; font-size: 0.86rem; }
    .platform-row { grid-template-columns: 1fr; }
    .footer-grid { grid-template-columns: 1fr 1fr; }

    .spotlight,
    .spotlight--flip {
        grid-template-columns: 1fr;
        gap: 28px;
    }

    /* Media above the words on a narrow screen, every row — alternating sides
       has no meaning in a single column, and the picture is the hook. */
    .spotlight .spotlight-media,
    .spotlight--flip .spotlight-media { order: -1; }

    .spotlights { gap: 76px; }
    .spotlight-body { max-width: none; }

    .showcase-strip {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        margin-top: 60px;
        padding-top: 44px;
    }

    .about-cols { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 760px) {
    .container { padding: 0 20px; }
    .nav-toggle { display: grid; place-items: center; }

    body.has-hero .site-header:not(.is-stuck) {
        background: rgba(5, 10, 18, 0.45);
        backdrop-filter: blur(8px);
    }

    .main-nav {
        position: absolute;
        top: 72px;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        padding: 0 20px;
        max-height: 0;
        overflow: hidden;
        background: rgba(5, 10, 18, 0.98);
        backdrop-filter: blur(14px);
        border-bottom: 1px solid transparent;
        transition: max-height 0.26s ease, padding 0.26s ease;
    }

    .main-nav.open {
        max-height: 640px;
        padding: 10px 20px 20px;
        border-bottom-color: var(--line);
    }

    .main-nav a { padding: 12px 8px; font-size: 1rem; }

    .lang-switch {
        width: 100%;
        margin: 8px 0 0;
        padding: 8px 0 0;
        border-left: 0;
        border-top: 1px solid var(--line);
    }

    .lang-btn { padding: 8px 8px 8px 0; }

    .lang-menu {
        position: static;
        width: 100%;
        margin-top: 6px;
        background: rgba(120, 195, 240, 0.05);
        box-shadow: none;
    }

    .hero {
        padding: 108px 0 76px;
        align-items: center;
    }

    /* On a phone the words cover most of the clip, so the wash goes heavier and
       the vignette is dropped — at this width there are no bright edges left to
       push back. */
    .hero-scrim {
        background:
            linear-gradient(rgba(5, 10, 18, 0.68), rgba(5, 10, 18, 0.68)),
            linear-gradient(to bottom,
                rgba(5, 10, 18, 0.62) 0%,
                rgba(5, 10, 18, 0) 30%,
                rgba(5, 10, 18, 0) 60%,
                var(--ink-900) 100%);
    }

    .hero-scroll { display: none; }

    .specs li {
        flex: 1 1 100%;
        padding: 13px 20px;
        font-size: 0.74rem;
    }

    .specs li + li {
        border-left: 0;
        border-top: 1px solid var(--line);
    }

    .section { padding: 72px 0; }
    .section-tight { padding: 56px 0; }
    .section-header { margin-bottom: 38px; }

    .feature-grid { gap: 0; }
    .showcase-strip { grid-template-columns: 1fr; gap: 26px; }
    .about-cols { grid-template-columns: 1fr; gap: 22px; }
    .callout {
        grid-template-columns: 1fr;
        gap: 16px;
        padding: 32px 26px;
    }

    .callout-body { grid-column: 1; }
    .footer-grid { grid-template-columns: 1fr; gap: 32px; }
    .page-header { padding: 44px 0 30px; }
    .content-page { padding: 40px 0 72px; }
    .content-card { padding: 28px 24px; }

    .lightbox-close { position: fixed; top: 14px; right: 14px; }
    .lightbox-stage img,
    .lightbox-stage video { max-height: calc(100vh - 190px); }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    * {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* ============================ Hologram frames ============================

   The app no longer draws rounded boxes. Every panel, button and field there
   is a "hologram frame" (Hologramu/rust/src/ui/holo_frame.rs): the top-left
   and bottom-right corners are cut off like the edges of the wireframe
   triangles in the main menu and loading screen, the cut edges glow, the
   other two corners carry small HUD brackets, and large panels have faint
   scanlines. The site wears the same frame.

   How it is built, so it works on anything without touching the markup:
     - clip-path cuts the two corners (it also clips the 1px border there),
     - ::after lays the glowing cut edges, the brackets and the scanlines on
       top as background layers — on top, because a screenshot inside a
       .media-frame would otherwise cover them.
   Per component only the custom properties change:
     --cut   size of the cut corners        --acc   colour of the cut edges
     --blen  bracket length (0 = none)      --brk   bracket colour
     --scan  scanline layer (or none)

   The frame rules still hold: one solid colour per headline, flat fills, no
   blur blobs. The glow is a 1.5px line, not a halo.
   ======================================================================== */

.btn,
.media-frame,
.media-zoom,
.platform-card,
.pricing-card,
.callout,
.content-card,
.lang-menu,
.lightbox-close {
    --cut: 10px;
    --acc: rgba(76, 221, 255, 0.45);
    --blen: 0px;
    --brk: rgba(255, 115, 196, 0.7);
    --scan: none;
    position: relative;
    border-radius: 0;
    clip-path: polygon(
        var(--cut) 0, 100% 0,
        100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%,
        0 100%, 0 var(--cut)
    );
}

.btn::after,
.media-frame::after,
.media-zoom::after,
.platform-card::after,
.pricing-card::after,
.callout::after,
.content-card::after,
.lang-menu::after,
.lightbox-close::after {
    content: "";
    position: absolute;
    inset: -1px;
    z-index: 1;
    pointer-events: none;
    background:
        /* Cut edges: a line exactly on the diagonal the clip-path leaves. */
        linear-gradient(135deg,
            transparent calc(var(--cut) * 0.7071 - 1.5px),
            var(--acc) 0 calc(var(--cut) * 0.7071 + 0.5px),
            transparent 0) top left / var(--cut) var(--cut) no-repeat,
        linear-gradient(-45deg,
            transparent calc(var(--cut) * 0.7071 - 1.5px),
            var(--acc) 0 calc(var(--cut) * 0.7071 + 0.5px),
            transparent 0) bottom right / var(--cut) var(--cut) no-repeat,
        /* HUD brackets on the two corners that keep their square. */
        linear-gradient(var(--brk), var(--brk)) top right / var(--blen) 2px no-repeat,
        linear-gradient(var(--brk), var(--brk)) top right / 2px var(--blen) no-repeat,
        linear-gradient(var(--brk), var(--brk)) bottom left / var(--blen) 2px no-repeat,
        linear-gradient(var(--brk), var(--brk)) bottom left / 2px var(--blen) no-repeat,
        var(--scan);
    transition: opacity 0.16s ease;
}

/* The focus ring would be cut off at the corners along with everything
   else — draw it inside the frame instead. */
.btn:focus-visible,
.media-frame:focus-visible,
.lang-menu a:focus-visible,
.lightbox-close:focus-visible {
    outline-offset: -4px;
}

/* ---- Buttons: quiet at rest, the brackets arrive on hover (as in the app). */
.btn {
    --cut: 9px;
    --acc: rgba(255, 255, 255, 0.6);
}
.btn:hover {
    --blen: 8px;
    --brk: var(--pink);
}
.btn-ghost {
    --acc: var(--line-cyan);
}
.btn-ghost:hover {
    --acc: var(--pink);
}
.btn[aria-disabled="true"],
.btn.is-disabled {
    --acc: var(--line);
    --blen: 0px;
}

/* ---- Panels: pink cut edges, brackets and scanlines — the app's windows. */
.platform-card,
.pricing-card,
.callout,
.content-card {
    --cut: 16px;
    --acc: rgba(255, 115, 196, 0.55);
    --blen: 14px;
    --brk: rgba(255, 115, 196, 0.55);
    --scan: repeating-linear-gradient(to bottom,
        rgba(76, 221, 255, 0.035) 0 1px, transparent 1px 4px);
}
.platform-card.primary,
.pricing-card.featured {
    --acc: var(--pink);
    --brk: var(--pink);
}
.pricing-card.featured::before { border-radius: 0; }

/* ---- Pictures: a frame, no scanlines over the screenshot itself. */
.media-frame {
    --cut: 14px;
    --acc: rgba(76, 221, 255, 0.55);
}
.media-frame:hover {
    --acc: var(--pink);
    --blen: 16px;
    --brk: var(--pink);
}

.media-zoom,
.lightbox-close { --cut: 6px; }

.lang-menu {
    --cut: 8px;
    --blen: 8px;
}

/* Floating wireframe shapes behind the page (assets/js/holo-shapes.js) —
   the same star/heart/moon/ring/... that drift behind the app's main menu.
   Sits between the grid (z -2) and the content. */
.holo-shapes {
    position: fixed;
    inset: 0;
    width: 100vw;
    height: 100vh;
    z-index: -1;
    pointer-events: none;
}

@media print {
    .holo-shapes { display: none; }
}
