@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;400;500&family=Onest:wght@300;400;500;600&family=Unbounded:wght@200;300;400;500&display=swap');

:root {
    --font-display: "Unbounded", sans-serif;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* ===== Colors ===== */

:root,
:root[data-theme="dark"] {
    --dark: #222222;
    --dark-light: #333333;
    --dark-gray: #333333;
    --gray: #8DB5BE;
    --medium-gray: #909090;
    --light: #CCCCCC;
    --white: #FFFFFF;
    --bg: #0B0D14;
    --bg-elevated: #191a1c;
    --text: #d8d9db;
    --btn: #8DB5BE;
    --btn-hover: #cfd8da;

    --modal-veil: rgba(12, 13, 15, 0.2);

    --avatar-base: rgba(255, 255, 255, 0.14);

    --lock-veil: rgba(90, 90, 90, 0.07);
    --lock-border: #3d4046;
    --lock-border-hover: #6e747d;
}

:root[data-theme="light"] {
    --dark: #e6e6e6;
    --dark-light: #dddddd;
    --dark-gray: #d8d6cf;
    --gray: #3f7682;
    --medium-gray: #5f5f5f;
    --light: #444444;
    --white: #111111;
    --bg: #f3f1e7;
    --bg-elevated: #e9e6d6;
    --text: #2b2b2b;
    --btn: #5f8088;
    --btn-hover: #36545b;

    --modal-veil: rgba(255, 255, 255, 0.45);

    --avatar-base: #ffffff;

    --lock-veil: rgba(255, 255, 255, 0.3);
    --lock-border: #cfccbd;
    --lock-border-hover: #9d998a;
}

body {
    background: var(--bg);
    color: var(--text);
    font-family: 'Onest', sans-serif;

    font-size: clamp(11px, calc(0.3125vw + 8px), 14px);
    margin: 0 auto;
    line-height: 1.5;

    transition: color 0.3s ease;

    /* Column layout so a short page still puts the footer at the bottom of
       the screen rather than halfway up it. */
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100svh;
}

/* Takes the slack. A column so a page can hand its own height back with
   flex:1 and be centred in whatever is left (see .nf on 404). min-width:0
   because flex items refuse to shrink below their content otherwise, which
   would let a wide table widen the whole page. */
#content {
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
    min-width: 0;
}

#footer {
    flex: 0 0 auto;
}

p {
    line-height: 1.6;
}

/* ===== Fonts ===== */

h1 {
    font-family: var(--font-display);
    min-width: 0;
    font-size: 3em;
    font-weight: 300;
    line-height: 1.05;
    letter-spacing: -0.02em;
    margin: 0;
}

h2 {
    font-family: var(--font-display);
    font-size: 2em;
    line-height: 1.1;
    font-weight: 300;
    letter-spacing: -0.01em;
    margin: 0;
}

blockquote {
    line-height: 1;
}

.serif {
    font-family: "Onest", sans-serif;
    font-weight: 300;
}

.mono {
    font-family: "JetBrains Mono", monospace;
    font-weight: 300;
}

.georgia {
    font-family: "Georgia";
    font-weight: 300;
}

.fs-xl {
    font-size: 3em;
    font-family: var(--font-display);
    font-weight: 300;
    letter-spacing: -0.02em;
    line-height: 1.05;
}

.fs-l {
    font-size: 2em;
}

.fs-m {
    font-size: 1.2em;
    font-weight: 400;
}

.fs-s {
    font-size: 0.8em;
}

.caps {
    text-transform: uppercase;
    letter-spacing: 0.2em;
}

.gray {
    color: var(--medium-gray);
}

/* All gray body paragraphs share one size & weight. Size is in em, so it
   scales with the responsive base font (16px on mobile, 14px on desktop).
   Small caps labels keep their own size and are excluded via :not(.caps). */
.gray:not(.caps) {
    font-size: 1.25em;
    font-weight: 400;
    line-height: 1.6;
}

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

.fs-m.white.serif {
    font-family: var(--font-display);
    font-size: 1.4em;
    font-weight: 500;
    letter-spacing: 0.01em;
    line-height: 1.35;
}

.headline {
    font-family: var(--font-display);
    font-size: 1.5em;
    font-weight: 400;
    line-height: 1.4;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--white);
}

a {
    color: var(--gray);
}

/* ===== Flex ===== */

.row {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
    min-width: 0;
}

.column {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.gap-10 {
    gap: 10px;
}

.gap-20 {
    gap: 20px;
}

.gap-40 {
    gap: 40px;
}

.gap-40 > .gap-10 {
    gap: 16px;
}

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

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

.grid-2 {
    grid-template-columns: repeat(2, 1fr);
}

.grid-1 {
    grid-template-columns: repeat(1, 1fr);
}

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

.button {
    font-size: 10px;
    font-family: var(--font-display);
    text-transform: uppercase;
    text-decoration: none;
    font-weight: 400;
    padding: 11px 14px;
    background: none;
    color: var(--btn);
    border: 1px solid var(--btn);
    transition: 0.3s ease all;
    letter-spacing: 0.06em;
}

.button:hover {
    color: var(--btn-hover);
    border: 1px solid var(--btn-hover);
}

.button:disabled,
.locked-modal__box .paywall-cta:disabled {
    opacity: 0.4;
    background: rgba(255, 255, 255, 0.06);
    cursor: default;
}

.button:disabled:hover {
    color: var(--btn);
    border: 1px solid var(--btn);
}

#themeToggle {
    cursor: pointer;
    padding: 0;
    border: none;
    background: none;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--btn);
}

#themeToggle:hover {
    border: none;
    color: var(--btn-hover);
}

#themeToggle .icon {
    width: 20px;
    height: 20px;
    display: none;
    fill: currentColor;
}

:root[data-theme="dark"] #themeToggle .icon-sun {
    display: block;
}

:root[data-theme="light"] #themeToggle .icon-moon {
    display: block;
}

/* ====== Language select ====== */

.lang-select {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--medium-gray);
    transition: color 0.3s ease;
}

.lang-select:hover {
    color: var(--btn-hover);
}

.lang-globe {
    width: 14px;
    height: 14px;
    flex: 0 0 auto;
}

.lang-code {
    font-family: "JetBrains Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.1em;
    line-height: 1;
}

/* Native <select> keeps real dropdown behaviour (and the OS picker on
   mobile), but stretched invisibly over the whole block so the globe is
   part of the hit area — not just the letters. */
.lang-select select {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    appearance: none;
    -webkit-appearance: none;
    background: none;
    border: none;
    outline: none;
    padding: 0;
    margin: 0;
    opacity: 0;
    cursor: pointer;
    font-family: "JetBrains Mono", monospace;
    font-size: 10px;
}

/* The open dropdown is drawn by the OS, so its list needs readable colors
   of its own — inherit would leave it transparent on some platforms. */
.lang-select option {
    background: var(--bg-elevated);
    color: var(--text);
}

/* ====== Header button (tighter than the footer CTA) ====== */

#header .button {
    font-size: 9px;
    padding: 9px 12px;
    white-space: nowrap;
}

/* ====== Profile visibility switch ====== */

/* No box: a sentence stating the current state, then an eye. Sits at the
   right edge of the column. Two variants share these styles — a real
   checkbox for the owner, and a link into the login for a signed-out
   visitor, whose state comes from .is-on instead of :checked. */
.vis {
    /* Sits in .avatar-row, so it is pushed to the far right of that row and
       shares its vertical centring with the name. */
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
    text-decoration: none;
}

.vis input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.vis-face {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    color: var(--medium-gray);
    transition: color 0.25s ease;
}

.vis-icon {
    width: 19px;
    height: 19px;
    flex: 0 0 auto;
}

/* Exactly one eye and one sentence are ever shown. */
.vis-on, .vis-text-on { display: none; }

.vis input:checked ~ .vis-face .vis-on,
.vis.is-on .vis-face .vis-on { display: block; }

.vis input:checked ~ .vis-face .vis-off,
.vis.is-on .vis-face .vis-off { display: none; }

.vis input:checked ~ .vis-face .vis-text-on,
.vis.is-on .vis-face .vis-text-on { display: inline; }

.vis input:checked ~ .vis-face .vis-text-off,
.vis.is-on .vis-face .vis-text-off { display: none; }

.vis-text {
    font-family: "JetBrains Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1.2;
    text-align: right;
}

/* Public is the state worth noticing, so it is the one that lights up. */
.vis input:checked ~ .vis-face,
.vis.is-on .vis-face { color: var(--btn); }

.vis:hover .vis-face { color: var(--text); }
.vis:hover input:checked ~ .vis-face,
.vis.is-on:hover .vis-face { color: var(--btn-hover); }

/* Keyboard focus has to survive hiding the native control. */
.vis input:focus-visible ~ .vis-face {
    outline: 1px solid var(--btn-hover);
    outline-offset: 4px;
}

.vis-note {
    font-style: normal;
    font-family: "JetBrains Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--gray);
}

/* ====== Named metric rows ====== */

.mrows {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 26px;
}

/* No borders — spacing alone separates the rows. */
.mrow { padding: 0; }

.mrow-top {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 6px 12px;
}

/* Name is the label: mono caps, spaced. The symbol rides in front of it,
   small and muted — present, not the focus. */
.mrow-name {
    display: inline-flex;
    align-items: baseline;
    flex-wrap: wrap;
    min-width: 0;
    gap: 9px;
    font-family: var(--font-display);
    font-size: 1.15em;
    font-weight: 400;
    letter-spacing: 0.01em;
    color: var(--white);
}

.mrow-sym {
    font-family: "Georgia", serif;
    font-style: normal;
    font-size: 14px;
    color: var(--medium-gray);
}

.mrow-val {
    font-family: var(--font-display);
    font-variant-numeric: tabular-nums;
    color: var(--medium-gray);
    font-size: 0.9em;
    white-space: nowrap;
}
.mrow-val b { font-weight: 500; font-size: 2.1em; color: var(--white); }

/* One continuous bar with a gradient fill — a real chart, not ten stubs. */
.mrow-bar {
    height: 6px;
    margin-top: 12px;
    background: var(--dark-gray);
    overflow: visible;
}

/* The gradient is anchored to the FULL track, not to the fill: background-size
   stretches it so its 0%→100% maps to value 0→10. A short bar therefore shows
   only the dim start of the gradient; a full bar reaches the bright end.
   --v (value × 10) comes from the inline style next to the width.

   Glow via drop-shadow, which samples the rendered pixels — the transparent
   left casts almost nothing, the bright right casts the most, so the glow
   follows the gradient and grows with the value on its own. */
.mrow-bar span {
    display: block;
    height: 100%;
    background: linear-gradient(90deg, transparent, var(--btn) 72%, var(--btn-hover));
    background-repeat: no-repeat;
    background-size: calc(10000% / var(--v, 100)) 100%;
    filter: drop-shadow(0 0 5px var(--btn)) drop-shadow(0 0 11px var(--btn));
    transition: width 0.4s ease;
}

/* Description carries the meaning, so it is the readable size — bigger than
   the mono label above it. */
.mrow-desc {
    margin: 12px 0 0;
    font-family: "JetBrains Mono", monospace;
    font-size: 9.5px;
    line-height: 1.6;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--medium-gray);
    /* Up to two lines; anything longer is clipped with an ellipsis. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

@media (max-width: 700px) {
    .mrow-desc { font-size: 9px; }
}

/* Genome score — big, set off from the metric rows by a hairline. */
.score {
    margin-top: 44px;
    padding-top: 30px;
    border-top: 1px solid var(--dark-gray);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.score-label {
    font-family: "JetBrains Mono", monospace;
    font-size: 12px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--medium-gray);
}
.score-val {
    font-family: var(--font-display);
    font-size: clamp(13px, 1.9vw, 20px);
    line-height: 1;
    color: var(--white);
    font-variant-numeric: tabular-nums;
}

/* ====== Reg wall — shown to a logged-out visitor on a profile ====== */
.regwall {
    max-width: 460px;
    margin: 0 auto;
    text-align: center;
    padding: 34px 30px;
    border-radius: 22px;
    border: 1px solid var(--dark-gray);
    background: radial-gradient(120% 120% at 50% 0%, rgba(141,181,190,0.14), transparent 60%), var(--bg-elevated);
}
.regwall-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 16px;
    font-family: "JetBrains Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--gray);
}
.regwall-badge svg { width: 13px; height: 13px; }
.regwall h3 {
    font-family: var(--font-display);
    font-weight: 400;
    font-size: 22px;
    line-height: 1.2;
    color: var(--white);
    margin-bottom: 10px;
}
.regwall p {
    font-size: 14px;
    line-height: 1.55;
    color: var(--medium-gray);
    margin-bottom: 22px;
}
.regwall a {
    display: inline-block;
    padding: 13px 26px;
    border-radius: 999px;
    background: var(--btn);
    color: var(--bg);
    font-family: var(--font-display);
    font-size: 12px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    text-decoration: none;
    transition: 0.25s ease all;
}
.regwall a:hover { background: var(--btn-hover); }

/* ====== Ego metrics: three radial gauges in a row ====== */
.egos {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
}

/* Outlined block. Desktop: 3 in a row, content stacked in a column. */
.ego {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    padding: 26px 24px;
    border: 1px solid var(--dark-gray);
}
.ego-body { display: flex; flex-direction: column; }

/* Mobile: blocks stack in a column, content inside runs in a row. */
@media (max-width: 700px) {
    .egos { grid-template-columns: 1fr; gap: 12px; }
    .ego { flex-direction: row; align-items: center; gap: 20px; padding: 20px; }
    .ego-ring { flex: 0 0 auto; }
    .ego-name { margin-top: 0; }
}

.ego-ring {
    position: relative;
    width: 104px;
    height: 104px;
}

/* Track + progress arc, both masked to a thin ring. The arc echoes the metric
   bars: it starts near-transparent and ramps to the bright end, with a glow
   that grows toward the value. --p (0–100) sets the swept angle. */
.ego-ring::before,
.ego-ring::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 50%;
    -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 6px));
            mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 6px));
}
.ego-ring::before { background: var(--dark-gray); }
.ego-ring::after {
    background: conic-gradient(from -90deg,
        color-mix(in srgb, var(--btn) 40%, transparent) 0deg,
        var(--btn) calc(var(--p) * 2.2deg),
        var(--btn-hover) calc(var(--p) * 3.6deg),
        transparent calc(var(--p) * 3.6deg));
    filter: drop-shadow(0 0 6px color-mix(in srgb, var(--btn) 60%, transparent));
}

/* A single number, centred in the ring. */
.ego-num {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-display);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: 1.7em;
    color: var(--white);
}

.ego-name {
    margin-top: 18px;
    font-family: var(--font-display);
    font-size: 1.1em;
    font-weight: 400;
    letter-spacing: 0.01em;
    color: var(--white);
}

/* Same register as .mrow-desc — uppercase mono, muted, spaced. */
.ego-desc {
    margin: 10px 0 0;
    font-family: "JetBrains Mono", monospace;
    font-size: 10px;
    line-height: 1.7;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--medium-gray);
}

/* ====== Owner's invite codes (profile page) ====== */

.own-invites {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 4px;
}

.own-invites .pw-codes {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0;
}

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

/* Icon plus label on wide screens, icon alone on phones — the header already
   carries four controls and the label is the only expendable part. */
.login-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    /* No padding: the language select and theme toggle have none either, so
       the flex gap alone sets the rhythm. Padding here made the space around
       this one control read wider than the rest. */
    padding: 0;
    color: var(--medium-gray);
    text-decoration: none;
    font-family: var(--font-display);
    font-size: 9px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
    transition: 0.3s ease all;
}

.login-btn svg {
    width: 15px;
    height: 15px;
    flex: 0 0 auto;
    /* Nudges into the doorway on hover — the icon is an arrow going in. */
    transition: transform 0.3s ease;
}

.login-btn:hover {
    color: var(--btn-hover);
}

.login-btn:hover svg { transform: translateX(2px); }

@media (max-width: 700px) {
    .login-btn { gap: 0; }
    .login-btn span { display: none; }
    .login-btn svg { width: 17px; height: 17px; }
}

/* ====== Internal nav (admins only) ====== */

/* A strip under the footer listing pages nothing else links to. Deliberately
   quiet: it is a tool, not part of the site. */
.adm {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px 18px;
    padding: 14px 20px 22px;
    border-top: 1px solid var(--dark-gray);
    background: var(--bg);
}

.adm a {
    font-family: "JetBrains Mono", monospace;
    font-size: 10px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--dark-light);
    transition: color 0.3s ease;
}

.adm a:hover { color: var(--btn-hover); }

/* Where you already are. */
.adm a.is-here { color: var(--gray); }

/* ====== Account menu (signed in) ====== */

.acct {
    position: relative;
    display: inline-flex;
}

/* Avatar doubles as the menu trigger. The initial sits underneath the photo
   and shows through whenever the image is missing or fails to load. */
.acct-btn {
    position: relative;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid var(--dark-gray);
    border-radius: 50%;
    background: var(--bg-elevated);
    color: var(--text);
    cursor: pointer;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: border-color 0.3s ease;
}

.acct-btn:hover,
.acct-btn[aria-expanded="true"] {
    border-color: var(--btn-hover);
}

.acct-btn img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.acct-initial {
    font-family: var(--font-display);
    font-size: 11px;
    font-weight: 400;
    line-height: 1;
    color: var(--text);
}

.acct-menu {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 20;
    min-width: 190px;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--dark-gray);
    background: var(--bg-elevated);
}

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

.acct-menu a {
    padding: 12px 16px;
    font-family: var(--font-display);
    font-size: 9px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--btn);
    white-space: nowrap;
    transition: 0.3s ease all;
}

.acct-menu a + a {
    border-top: 1px solid var(--dark-gray);
}

.acct-menu a:hover {
    color: var(--btn-hover);
    background: var(--dark-gray);
}

/* Logout is a POST form (CSRF-safe), styled to match the anchor menu items. */
.acct-menu .acct-logout { margin: 0; border-top: 1px solid var(--dark-gray); }
.acct-menu .acct-logout button {
    display: block;
    width: 100%;
    padding: 12px 16px;
    border: none;
    background: none;
    text-align: left;
    cursor: pointer;
    font-family: var(--font-display);
    font-size: 9px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--btn);
    white-space: nowrap;
    transition: 0.3s ease all;
}
.acct-menu .acct-logout button:hover {
    color: var(--btn-hover);
    background: var(--dark-gray);
}

/* ====== Footer community link ====== */

/* Secondary to the CTA above it: a plain link, not a second button. */
.footer-community {
    font-family: "JetBrains Mono", monospace;
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--medium-gray);
    transition: color 0.3s ease;
}

.footer-community:hover {
    color: var(--btn-hover);
}

/* ====== Logo (monochrome SVG, recolored per theme) ====== */

.logo {
    display: inline-block;
    line-height: 0;
    text-decoration: none;
}

.logo img {
    display: block;
    transition: filter 0.3s ease;
}

:root[data-theme="light"] .logo img {
    filter: invert(0.83);
}

#Page {
    display: flex;
    flex-direction: row;
    width: 100%;
    padding: 0px;
}

#header {
    padding: 20px;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
}

/* One row: logo left, CTA centred, community right. Three grid columns
   rather than space-between, so the button sits in the true centre of the
   page instead of the middle of whatever is left over. */
#footer {
    margin: 80px 0 0 0;
    /* Same as #header, so the logos line up on both edges of the page. */
    padding: 20px;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 20px;
    border-top: 1px solid var(--dark-gray);
}

#footer .logo { justify-self: start; }
#footer .button { justify-self: center; }
#footer .footer-community { justify-self: end; text-align: right; }

/* Phones: stack instead of squeezing three items into 375px, which forced
   8px type to make them fit. */
@media (max-width: 700px) {
    #footer {
        grid-template-columns: 1fr;
        justify-items: center;
        gap: 22px;
        margin-top: 56px;
        padding: 28px 20px;
    }

    #footer .logo,
    #footer .button,
    #footer .footer-community { justify-self: center; text-align: center; }
}

/* ====== Noograph ====== */

#NoographWrapper {
    flex: 0 0 auto;
    width: min(80vh, 48vw);
    height: min(80vh, 48vw);
    position: sticky;
    top: 20px;
    padding: 10px;
}

#Noograph {
    position: relative;
    width: 100%;
    height: 100%;
}

#Noograph #Ego {
    width: 80%;
    height: 80%;
    position: absolute;
    top: 10%;
    left: 10%;
    z-index: 1;
}

#Noograph #Graph {
    width: 100%;
    height: 100%;
    position: absolute;
    z-index: 2;

}

/* ====== Analytics ====== */

#Analytics {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    padding: 0 40px 40px 40px;
    gap: 80px;
}

.section {
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 20px;
    min-width: 0;
}

.section>header {
    font-size: 14px;
    letter-spacing: 3px;
    text-transform: uppercase;
    font-family: "JetBrains Mono", monospace;
    letter-spacing: 2px;
    color: var(--gray);
    border-bottom: 1px solid var(--dark-gray);
    padding: 5px 0;
}

.section-label {
    color: var(--medium-gray);
    background: var(--bg);
}

#thumb {
    border-radius: 100px;
}

#genomeScore {
    color: var(--white);
    font-weight: 600;
}

/* ====== Avatar ====== */

.avatar-row {
    display: flex;
    align-items: center;
    gap: 12px;
}

.avatar {
    display: block;
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    /* fallback fill for the polygon when no palette is available; the
       gradient is set as an inline attribute, so no `fill` rule here —
       a stylesheet fill would override it and kill the gradient. */
    color: var(--white);
}

.avatar svg {
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
}

.avatar-base {
    fill: var(--avatar-base);
}

/* ====== Analytics > Metrics ====== */

.grid-element {
    border: 1px solid var(--dark-gray);
    padding: 10px;
}

.grid-3 .grid-element {
    min-height: 120px;
    justify-content: space-between;
}

.grid-3 .grid-element .fs-xl {
    text-align: right;
}

/* ====== Analytics > Dominant Pattern ====== */

.tags {
    display: flex;
    flex-direction: row;
    gap: 4px;
    flex-wrap: wrap;
}

.tag {
    display: flex;
    padding: 8px 15px;
    border: 1px solid var(--gray);
    border-radius: 100px;
    line-height: 1;
}

/* ====== Locks ====== */

.locked {
    position: relative;
    padding: 10px;
    border: 1px solid var(--lock-border);
    cursor: pointer;
    transition: 0.2s ease all;
}

.locked:after {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;

    background: url(../img/lock.svg) var(--lock-veil);
    background-position: center center;
    background-repeat: no-repeat;
    z-index: 1;

    -webkit-backdrop-filter: blur(18px);
    backdrop-filter: blur(18px);
    transition: 0.2s ease all;
}

.locked:hover {
    border: 1px solid var(--lock-border-hover);
}

.locked:hover:after {
    -webkit-backdrop-filter: blur(24px);
    backdrop-filter: blur(24px);
}

/* Locked modal — absolutely positioned overlay, hidden by default */
.locked-modal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;

    height: 100vh;
    height: 100dvh;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: var(--modal-veil);

    font-size: 16px;
    z-index: 100;
}

.locked-modal.is-open {
    display: flex;
    -webkit-backdrop-filter: blur(20px) saturate(175%);
    backdrop-filter: blur(20px) saturate(175%);
    animation: modal-fade-in 0.35s ease both;
}

.locked-modal__box {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 20px;
    max-width: 340px;
    width: 100%;
    padding: 40px 0;
    background: none;
    border: none;
}

.locked-modal__box .button {
    align-self: flex-start;
}

.locked-modal__close {
    position: absolute;

    top: calc(22px + env(safe-area-inset-top, 0px));
    right: calc(22px + env(safe-area-inset-right, 0px));
    width: 26px;
    height: 26px;
    padding: 0;
    background: none;
    border: none;
    color: var(--medium-gray);
    cursor: pointer;
    transition: color 0.3s ease;
}

.locked-modal__close svg {
    display: block;
    width: 100%;
    height: 100%;
}

.locked-modal__close:hover {
    color: var(--white);
}

/* Paywall views — only the active one is shown */
.locked-modal__view {
    display: none;
    flex-direction: column;
    gap: 20px;
}

.locked-modal__view.is-active {
    display: flex;
}

.locked-modal h2 {
    font-size: 1.6em;
}

.locked-modal .paywall-features li,
.locked-modal .paywall-steps li {
    font-size: 1.05em;
}

.locked-modal .gray:not(.caps) {
    font-size: 1em;
}

.locked-modal .pw-note {
    font-size: 0.8em;
    line-height: 1.5;
}

.pw-codes {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Codes are char(8) in the DB — smaller type and tighter tracking so five
   chips still fit the narrow modal column. */
.pw-code {
    min-width: 8.4em;
    padding: 6px 8px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--dark-gray);
    color: var(--text);
    font-family: "JetBrains Mono", monospace;
    font-size: 0.7em;
    letter-spacing: 0.06em;
    text-align: center;
    cursor: pointer;
    transition: 0.2s ease all;
}

.pw-code:hover {
    border-color: var(--btn);
    color: var(--white);
}

.pw-code.is-copied {
    border-color: var(--btn);
    color: var(--btn);
}

.pw-code.is-used {
    opacity: 0.35;
    cursor: default;
    text-decoration: line-through;
}

.pw-code.is-used:hover {
    border-color: var(--dark-gray);
    color: var(--text);
}

.locked-modal .button {
    font-size: 12px;
}

.locked-modal .locked-modal__link {
    font-size: 12px;
}

@keyframes modal-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .locked-modal.is-open {
        animation: none;
    }
}

.spark-list,
.paywall-features,
.paywall-steps {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin: 16px 0;
    padding: 0;
    list-style: none;
    counter-reset: step;
}

.spark-list li,
.paywall-features li,
.paywall-steps li {
    display: flex;
    align-items: center;
    gap: 10px;
    color: var(--text);
    line-height: 1.4;
}

.spark-list li::before,
.paywall-features li::before {
    content: "";
    flex: 0 0 auto;
    width: 13px;
    height: 13px;
    background-color: var(--gray);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.5C12.7 7.5 16.5 11.3 22.5 12C16.5 12.7 12.7 16.5 12 22.5C11.3 16.5 7.5 12.7 1.5 12C7.5 11.3 11.3 7.5 12 1.5Z'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1.5C12.7 7.5 16.5 11.3 22.5 12C16.5 12.7 12.7 16.5 12 22.5C11.3 16.5 7.5 12.7 1.5 12C7.5 11.3 11.3 7.5 12 1.5Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.spark-list li {
    align-items: flex-start;
    color: var(--medium-gray);
    font-size: 1.25em;
    line-height: 1.6;
}

.spark-list li::before {
    margin-top: 0.45em;
}

/* Numbered steps for the free-access view */
.paywall-steps li {
    counter-increment: step;
}

.paywall-steps li::before {
    content: counter(step);
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-family: "JetBrains Mono", monospace;
    color: var(--gray);
    border: 1px solid var(--gray);
    border-radius: 100px;
}

.locked-modal__box .paywall-cta {
    align-self: stretch;
    text-align: center;
    padding: 14px;
    cursor: pointer;
}

.locked-modal__link {
    align-self: center;
    background: none;
    border: none;
    padding: 4px;
    color: var(--gray);
    font-family: "JetBrains Mono", monospace;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 1px;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
    transition: color 0.3s ease;
}

.locked-modal__link:hover {
    color: var(--white);
}

#preloader {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #000;

    animation: preloader-failsafe 0.8s 6s forwards;
}

#preloader svg {
    width: min(23vmin, 150px);
    height: auto;
    overflow: visible;
}

#preloader .pre-data {
    fill: none;
    stroke: #ffffff;
    stroke-width: 2.5;
    stroke-linejoin: round;
    filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.55));
}

#preloader.is-done {
    display: none;
}

@keyframes preloader-failsafe {
    to { opacity: 0; visibility: hidden; }
}

@media (max-width: 960px) {
    body {
        font-size: 16px;
    }

    #Page {
        flex-direction: column;
    }

    /* ====== Noograph ====== */

    #NoographWrapper {
        width: 100%;
        aspect-ratio: 1 / 1;
        position: relative;
        height: auto;
    }

    #Analytics {
        padding: 0;
    }

    /* Three controls beside the logo — keep them off it and off each other. */
    #header {
        gap: 12px;
    }

    /* Tight between the icon controls, so they read as one cluster… */
    #header .row.gap-20 {
        gap: 6px;
    }

    /* …and a wider step before the CTA, which is a different kind of thing.
       :last-child covers the account menu too, once signed in. */
    #header .row.gap-20 > :last-child {
        margin-left: 10px;
    }

    #header .button {
        padding: 8px 9px;
        font-size: 8px;
        letter-spacing: 0.03em;
    }

    .lang-select {
        gap: 4px;
    }

    .lang-globe {
        width: 13px;
        height: 13px;
    }

    .lang-code {
        font-size: 9px;
        letter-spacing: 0.06em;
    }

}
