/* VELCREST SITE REPORT — the presenter, inside the portal
   ==========================================================================
   Ported from sitereport/app/css/app.css, which was built to
   docs/SITE-REPORT-UI.md. The values are that spec's; what changed is only
   that this sheet reuses the portal's own tokens instead of redeclaring them,
   so there is one Nocturne system on this origin and not two.

   WHY THIS IS A FULL-SCREEN OVERLAY AND NOT A DASHBOARD VIEW
   ---------------------------------------------------------
   Joe shares his screen with a prospect while this runs. The portal's sidebar
   carries his CLIENT LIST. Rendering the report inside the normal dashboard
   chrome would put other clients' company names on a stranger's screen, in a
   recorded Zoom call, every single time. So `body.sr-presenting` takes the
   viewport over completely: sidebar, mobile header and content wrapper are all
   hidden, and nothing of the portal remains visible.

   SCOPING RULE: every selector below is under `.sr-stage`, `.sr-` or
   `body.sr-presenting`. The portal is live and holds real client data — no
   rule in this file may change how any existing screen renders.

   Brand rules enforced here, from CLAUDE.md:
     - No button has a solid fill. Both styles are transparent; hover brings
       amber to the border and the label.
     - Nothing is light. One ground: --color-void.
     - Amber is a sparse signal, never a background block. The only amber fill
       is the 8x8px pulse.
     - No pills, gradients, glows, shadows, emoji or icon glyphs. 2px radius.
   ========================================================================== */

/* ------------------------------------------------ the take-over */

body.sr-presenting #sidebar,
body.sr-presenting .mobile-header,
body.sr-presenting #main-content {
    display: none !important;
}

body.sr-presenting {
    overflow: hidden;
}

.sr-stage {
    position: fixed;
    inset: 0;
    z-index: 900;
    background: var(--color-void);
    color: var(--color-text);
    font-family: var(--font-sans);
    overflow: hidden;

    /* At a 1280x800 share window this resolves to about 16px, which is what
       the type scale below was drawn against. */
    font-size: clamp(15px, min(1.25vw, 2vh), 20px);

    --sr-gutter: 5rem;
    --sr-col-max: 62.5rem;
    /* One use only: the empty image area of the link-preview card. */
    --sr-absence: #3c3c39;
}

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

/* An explicit `display` beats the browser's own [hidden] rule, so a hidden
   inline-flex button would otherwise stay on screen. */
.sr-stage [hidden] {
    display: none !important;
}

/* ------------------------------------------------------------ the rail */

.sr-rail {
    height: 4rem;
    padding: 0 var(--sr-gutter);
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* Transparent at all times — the standing header rule. */
    background: none;
}

.sr-brand {
    display: flex;
    align-items: center;
    gap: 12px;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.sr-brand img {
    height: 34px;
    width: auto;
    display: block;
}

.sr-brand span {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: 1.125rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
}

/* The logo is a control but must not look like one. Only the wordmark warms. */
.sr-brand:hover span,
.sr-brand:focus-visible span {
    color: var(--color-signal);
}

/* The right-hand group. The exit control sits in the flex flow beside the
   domain rather than pinned to the corner — pinned, it overlapped the domain,
   which reads as broken software on a shared screen. */
.sr-rail-right {
    display: flex;
    align-items: center;
    gap: 2rem;
    min-width: 0;
}

.sr-rail-target {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    text-align: right;
    min-width: 0;
}

/* The domain is attacker-supplied. It is already middle-ellipsised in JS; this
   stops a pathological one from pushing the exit control off screen anyway. */
.sr-rail-domain {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sr-rail-label,
.sr-rail-checked {
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--color-text-2);
}

.sr-rail-domain {
    font-size: 1.125rem;
    color: var(--color-text);
    flex: 1 1 auto;
}

/* ----------------------------------------------------------- the column */

.sr-screen {
    display: none;
    padding: 5rem var(--sr-gutter) 0;
    max-width: calc(var(--sr-col-max) + var(--sr-gutter) * 2);
}

.sr-screen[data-active='true'] {
    display: block;
}

.sr-screen[data-active='true'] > * {
    animation: sr-rise 300ms var(--ease-out-brand) both;
}

.sr-screen[data-active='true'] > *:nth-child(2) { animation-delay: 70ms; }
.sr-screen[data-active='true'] > *:nth-child(3) { animation-delay: 140ms; }
.sr-screen[data-active='true'] > *:nth-child(4) { animation-delay: 210ms; }

@keyframes sr-rise {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
}

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

.sr-eyebrow {
    display: flex;
    align-items: center;
    gap: 12px;
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--color-text-2);
    margin: 0 0 2rem;
}

/* The eyebrow rule. One amber mark per screen, maximum. */
.sr-eyebrow::before {
    content: '';
    width: 28px;
    height: 2px;
    background: var(--color-signal);
    flex: none;
}

.sr-headline {
    font-family: var(--font-display);
    font-weight: 500;
    text-transform: uppercase;
    color: var(--color-text);
    margin: 0;
    text-wrap: balance;
}

/* The step is chosen at render time from the headline's character count. */
.sr-headline[data-step='A'] { font-size: 4rem;    letter-spacing: 0.03em;  line-height: 0.98; max-width: 16ch; }
.sr-headline[data-step='B'] { font-size: 3.25rem; letter-spacing: 0.03em;  line-height: 1;    max-width: 22ch; }
.sr-headline[data-step='C'] { font-size: 2.75rem; letter-spacing: 0.035em; line-height: 1.04; max-width: 28ch; }
.sr-headline[data-step='D'] { font-size: 2.5rem;  letter-spacing: 0.04em;  line-height: 1.06; max-width: 28ch; }

/* The constant finding marker. Identical on every finding — it carries no
   severity information and never varies, because a marker that changed would
   be a grade, and this tool does not grade anyone. */
.sr-sowhat {
    position: relative;
    padding-left: 1.5rem;
    margin: 2rem 0 0;
    font-size: 1.625rem;
    line-height: 1.45;
    color: var(--color-text);
    max-width: 46ch;
}

.sr-sowhat::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0.35em;
    bottom: 0.35em;
    width: 2px;
    background: var(--color-signal);
}

.sr-support {
    font-size: 1.25rem;
    line-height: 1.5;
    color: var(--color-text-2);
    max-width: 56ch;
}

.sr-ledger {
    list-style: none;
    margin: 0;
    padding: 0;
}

.sr-ledger li {
    font-size: 1.5rem;
    line-height: 1.35;
    color: var(--color-text);
    opacity: 0.55;
    padding: 0.25rem 0;
    transition: opacity 220ms var(--ease-out-brand);
}

.sr-ledger li[data-done='true'] {
    opacity: 1;
}

.sr-evidence {
    display: flex;
    gap: 3rem;
    margin-top: 3rem;
    flex-wrap: wrap;
}

.sr-evidence dt {
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--color-text-2);
    margin: 0 0 0.5rem;
}

.sr-evidence dd {
    margin: 0;
    font-size: 1.375rem;
    line-height: 1.4;
    color: var(--color-text);
}

.sr-cue {
    margin-top: 3rem;
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--color-text-2);
}

/* --------------------------------------------------------- the pulse */
/* The one permitted amber fill: 8x8px, and never two at once. */

.sr-pulse {
    display: inline-block;
    width: 8px;
    height: 8px;
    background: var(--color-signal);
    margin-right: 12px;
    animation: sr-pulse 2000ms ease-in-out infinite;
}

@keyframes sr-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

/* ------------------------------------------------- link-preview card */
/* The one grey slab in the app. --sr-absence appears nowhere else. */

.sr-preview-card {
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius);
    max-width: 34rem;
    overflow: hidden;
    background: rgba(5, 5, 5, 0.7);
    margin-top: 2.5rem;
}

.sr-preview-card .sr-void-image {
    height: 14rem;
    background: var(--sr-absence);
}

.sr-preview-card .sr-meta {
    padding: 1.25rem;
}

.sr-preview-card .sr-meta-host {
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--color-text-2);
}

.sr-preview-card .sr-meta-title {
    font-size: 1.375rem;
    color: var(--color-text);
    margin: 0.5rem 0 0;
}

/* ------------------------------------------------------------ the recap */
/*
 * The screen the whole run builds to, and the only place the findings appear
 * together. There is no PDF and no email by decision (Joe, 2026-09-19), so
 * this IS the deliverable — which is why it gets the largest type here and the
 * most air around it. Restraint is the house style, so "the big moment" means
 * scale and space, never ornament.
 *
 * ONE amber rule runs the length of the list, not one per row: ten amber marks
 * would stop being a signal and start being decoration.
 */

.sr-recap-domain {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: 3.5rem;
    line-height: 1;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-text);
    margin: 0 0 2.5rem;
}

.sr-recap-list {
    list-style: none;
    margin: 0;
    padding: 0 0 0 2rem;
    border-left: 2px solid var(--color-signal);
    counter-reset: srrecap;
    max-width: 44ch;
}

.sr-recap-list li {
    counter-increment: srrecap;
    position: relative;
    padding: 0 0 0 3.25rem;
    margin: 0 0 var(--sr-recap-gap, 1.25rem);
    font-size: var(--sr-recap-size, 1.5rem);
    line-height: 1.25;
    color: var(--color-text);
}

.sr-recap-list li::before {
    content: counter(srrecap, decimal-leading-zero);
    position: absolute;
    left: 0;
    top: 0.15em;
    font-family: var(--font-sans);
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    color: var(--color-text-2);
    font-variant-numeric: tabular-nums;
}

/* Denser sets step down so the recap stays on one screen without scrolling,
   and never below the 15px screen-share legibility floor. */
.sr-recap-list[data-density='roomy']  { --sr-recap-size: 1.75rem; --sr-recap-gap: 1.5rem; }
.sr-recap-list[data-density='normal'] { --sr-recap-size: 1.5rem;  --sr-recap-gap: 1.25rem; }
.sr-recap-list[data-density='tight']  { --sr-recap-size: 1.25rem; --sr-recap-gap: 0.85rem; }

.sr-recap-more {
    margin: 2rem 0 0 2rem;
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-text-2);
}

/* --------------------------------------------------------- the controls */
/*
 * Bottom-left on the gutter, pinned so they do not move between screens — a
 * control that shifts position on every finding has to be re-found every time.
 * Always visible: on a live call a control that only appears when you wiggle
 * the mouse is a control you cannot rely on.
 */

.sr-controls {
    position: fixed;
    left: var(--sr-gutter);
    bottom: 2.5rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    opacity: 0.62;
    transition: opacity 250ms var(--ease-brand);
}

.sr-controls:hover,
.sr-controls:focus-within {
    opacity: 1;
}

/* No solid fills. Hover brings amber to border and label. */
.sr-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 40px;
    font-family: var(--font-sans);
    /* 15px is the Zoom legibility floor; the marketing site's 12px mushes
       under screen-share compression. */
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-text);
    background: transparent;
    border: 1px solid var(--color-line-strong);
    border-radius: var(--radius);
    padding: 0.6rem 1.25rem;
    cursor: pointer;
    transition: border-color 250ms ease, color 250ms ease, background-color 250ms ease;
}

.sr-btn:hover,
.sr-btn:focus-visible {
    border-color: var(--color-signal);
    color: var(--color-signal);
    background: var(--signal-wash);
}

/* Dimmed at the ends of the run, not hidden — a control that vanishes makes
   the row jump and makes him wonder what he pressed. */
.sr-btn:disabled {
    opacity: 0.32;
    cursor: default;
    border-color: var(--color-line-strong);
    color: var(--color-text);
    background: transparent;
}

.sr-btn-bare {
    border: none;
    background: transparent;
    padding: 0.6rem 0;
    color: var(--color-text-2);
    font-family: var(--font-sans);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    cursor: pointer;
}

.sr-btn-bare:hover,
.sr-btn-bare:focus-visible {
    color: var(--color-signal);
}

/* The way out. Quiet, and it never shrinks below its label. */
.sr-exit {
    flex: none;
}

.sr-stage :focus-visible {
    outline: 2px solid var(--color-signal);
    outline-offset: 3px;
}

/* ------------------------------------------- the launcher (in-dashboard) */

.sr-launch-field {
    display: block;
    width: 100%;
    max-width: 32ch;
    font-family: var(--font-sans);
    font-size: 1.375rem;
    line-height: 1.2;
    color: var(--color-text);
    background: transparent;
    border: none;
    border-bottom: 2px solid var(--color-line-field);
    border-radius: 0;
    padding: 0.5rem 0;
    outline: none;
    transition: border-color 250ms ease;
}

.sr-launch-field::placeholder {
    color: var(--color-text-2);
}

.sr-launch-field:focus {
    border-bottom-color: var(--color-signal);
}

.sr-actions {
    display: flex;
    gap: var(--spacing-md);
    align-items: center;
    flex-wrap: wrap;
    margin-top: var(--spacing-lg);
}

.sr-saved-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--spacing-md);
    padding: var(--spacing-sm) 0;
    border-bottom: 1px solid var(--color-line);
}

.sr-saved-row:last-child {
    border-bottom: none;
}

.sr-saved-host {
    font-size: 1rem;
    color: var(--color-text);
}

.sr-saved-when {
    font-size: 0.8125rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-text-2);
}

/* The estimator shows money and must never be on a shared screen. The warning
   is a hairline amber rule down the left, which is the one amber treatment the
   brand rules allow for this — never a filled banner. */
.sr-private {
    border-left: 2px solid var(--color-signal);
    padding-left: var(--spacing-md);
    margin: var(--spacing-md) 0;
}

.sr-private p {
    margin: 0;
    color: var(--color-text);
    font-size: 0.9375rem;
    line-height: 1.5;
}

/* ------------------------------------------------------ reduced motion */

@media (prefers-reduced-motion: reduce) {
    .sr-stage *,
    .sr-stage *::before,
    .sr-stage *::after {
        animation-duration: 1ms !important;
        animation-delay: 0ms !important;
        transition-duration: 1ms !important;
        transition-delay: 0ms !important;
    }
    .sr-pulse {
        animation: none;
        opacity: 1;
    }
}

/* ------------------------------------------ below the share window */

@media (max-width: 900px) {
    .sr-stage {
        --sr-gutter: 2rem;
    }
}
