/* ════════════════════════════════════════════════════════════════════
   Contact — Figma frame "Contact Us Flow" (node 219:475).

   219:475 is a flow of two states: 187:275 (base) is what this page
   renders, and 177:89 is the same screen with the Subject dropdown
   expanded (190:2). Nav and Footer in both come from base.html and are
   out of scope for this rebuild.

   Every value below was read off the frame and is pinned by
   tests/test_contact_design_fidelity.py against
   tests/design/contact_page_tokens.json. Do not adjust a number without
   changing the frame and re-extracting: the test will fail, by design.

   Four things that are easy to get wrong, and so are called out:

     - The frame's content box is 1120px (629 + 64 + 427). base.css's
       .container is 1100px wide with 20px of padding, which leaves 1060 —
       and because the form column is the flexible one, it would absorb the
       whole 60px shortfall on its own. main.container is widened for this
       page only; the header and footer own separate .container elements
       and keep 1100.
     - Nothing on this frame casts a shadow except the expanded dropdown,
       which a native <select> hands to the OS. base.css puts a 3px blue
       glow on :focus for every input on the site; it is cancelled below,
       because it is not in this design.
     - Two cyans. Eyebrow labels are #00bfff; the selected option inside
       the expanded dropdown is #00deff. They are not the same value.
     - base.css sets line-height 1.6 on body. Almost every text node in
       this frame is leading-normal, and inheriting 1.6 inflates all four
       controls and every row of the info card. The four roles that DO
       carry a numeric leading in the frame restate it below.

   No inline styles anywhere on this page: style-src-attr is hash-pinned
   (chaos_tester_csp_style_hashes.py).
   ════════════════════════════════════════════════════════════════════ */

:root {
    --ct-surface:    #0f172a;
    --ct-hairline:   rgba(51,65,85,0.7);
    --ct-label:      #e2e8f0;
    --ct-muted:      #b0b8c8;
    --ct-cyan:       #00bfff;
    --ct-cyan-pick:  #00deff;
    --ct-pick-bg:    #141f38;
    --ct-cta-ink:    #0d121a;
    --ct-ok:         #4ade80;
    --ct-content:    1120px;
}

/* The frame's own background fill. Sampled off the 187:275 render: the glow
   peaks at (50%, 30%) on #173948 and closes exactly one radius out, which is
   the SAME ellipse /status, /api and /ai-website-audit use — and NOT the
   landing/scan glow (60% 24% at 50% 58%). Scoped to the body class so it
   cannot leak onto any other page. */
body.contact-page {
    background:
        radial-gradient(ellipse 60% 30% at 50% 30%, #173948 0%, #0e1a2c 55%, rgba(6, 9, 20, 0) 100%),
        #020617;
    background-attachment: fixed;
}

/* The frame is 1280 wide with 80px of padding, so its content box is 1120.
   Scoped to main so the header's and footer's own .container are untouched. */
body.contact-page main.container {
    max-width: 1160px;
}

.contact {
    /* The frame puts 80px between the nav's bottom edge and the h1.
       main.container carries u-padding-y (80px top), but the site's header is
       `position: fixed` and 75px tall, so that padding clears the header by
       only 5px. This restores the frame's gap: 80 + 75 - 75 = 80 visible.
       Recompute if the header's height ever changes. */
    padding-top: 75px;
}

/* ── layout (187:286) ──────────────────────────────────────────────── */

.contact-grid {
    display: grid;
    /* minmax(0,1fr) rather than 1fr: a bare 1fr floors at min-content, and a
       long unbroken word in the textarea would push the column past 629px. */
    grid-template-columns: minmax(0, 1fr) 427px;
    gap: 64px;
    align-items: start;
}

/* ── form side (187:287) ───────────────────────────────────────────── */

.contact-form-side {
    display: flex;
    flex-direction: column;
    gap: 32px;
    min-width: 0;
}

.contact-head {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.contact-head h1 {
    margin: 0;
    font-size: 44px;
    font-weight: 700;
    line-height: 1.2;
    color: #ffffff;
}
.contact-hero-sub {
    margin: 0;
    font-size: 15px;
    font-weight: 400;
    line-height: 1.55;
    color: var(--ct-muted);
}

.contact-form {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.contact-field {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* base.css styles the bare `label` selector at 0.85rem/--text-muted with a
   4px bottom margin. The frame's labels are 13px semibold #e2e8f0 and the
   8px gap above owns the spacing. */
.contact-form label {
    display: block;
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    line-height: normal;
    color: var(--ct-label);
}

/* `.contact-form .contact-control`, not `.contact-control`: base.css styles
   `input[type="text"], input[type="number"], input[type="url"], select,
   textarea` in one rule, and the attribute selectors in it score 0-1-1 —
   higher than a bare class. A single-class selector here loses on the name
   field (type="text") while winning on the email field (type="email" is not
   in base.css's list), so the two adjacent controls would render with
   different backgrounds, borders, padding and font sizes. */
.contact-form .contact-control {
    width: 100%;
    padding: 12px 16px;
    background: var(--ct-surface);
    border: 1px solid rgba(51,65,85,0.7);
    border-radius: 8px;
    color: #ffffff;
    font-size: 14px;
    font-weight: 400;
    line-height: normal;
    transition: border-color .2s;
}
.contact-form .contact-control::placeholder {
    color: var(--ct-muted);
    opacity: 0.6;
}
/* base.css puts `box-shadow: 0 0 0 3px rgba(59,130,246,0.15)` on every
   focused input site-wide. No node in this frame has a shadow. The keyboard
   ring still comes from base.css's :focus-visible rule, restated below so
   it survives this override. */
.contact-control:focus {
    box-shadow: none;
    border-color: var(--ct-cyan);
}
.contact-control:focus-visible {
    outline: 2px solid var(--ct-cyan);
    outline-offset: 2px;
}
.contact-control[aria-invalid="true"] {
    border-color: #f87171;
}

.contact-textarea {
    height: 120px;
    min-height: 120px;
    resize: vertical;
}

/* Subject — 187:302 closed, 190:2 open.

   A native <select> popup is drawn by the OS and can take none of node
   190:2's values, so contact-select.js swaps the <select> for a real listbox
   (role=combobox + role=listbox) and keeps the <select> underneath as the
   field that carries the value and as the no-JS fallback. Behaviour is
   pinned by tests/test_contact_select_widget.py.

   Until that script runs — and forever if it does not — the <select> is what
   shows, styled to the closed state of the frame. */
.contact-select-wrap {
    position: relative;
    display: flex;
    flex-direction: column;
}
.contact-form .contact-select {
    appearance: none;
    -webkit-appearance: none;
    /* room for the chevron sitting in the 16px gutter */
    padding-right: 44px;
}
.contact-select-chevron {
    position: absolute;
    top: 50%;
    right: 16px;
    transform: translateY(-50%);
    font-size: 12px;
    line-height: 1;
    color: var(--ct-muted);
    pointer-events: none;
}
/* Best effort for the fallback popup: honoured by Chrome and Firefox on
   Windows/Linux, ignored by macOS, which is the whole reason the enhanced
   widget exists. */
.contact-form .contact-select option {
    background: #0f172a;
    color: #ffffff;
}

/* Once enhanced, the <select> is removed from view but stays in the form so
   it is still serialised. Not display:none — a hidden-but-submitted control
   is the point. */
.contact-select--enhanced,
.contact-select-chevron.is-replaced {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* The trigger reproduces the closed control exactly (187:302): same surface,
   border, radius and padding, with the value and the chevron pushed apart. */
.contact-form .contact-select-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    text-align: left;
    cursor: pointer;
}
.contact-select-trigger .contact-select-chevron {
    position: static;
    transform: none;
}
.contact-select-value {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The open panel (190:2).

   Absolute, not in flow: the frame's auto-layout pushes "Your Message" down
   to y=518 only because Figma cannot overlay, and a 0 8px 24px shadow is
   only ever painted on something meant to float. `top: 0` because the frame
   puts the panel at y=24 within the field group — exactly where the closed
   control sits — so it covers its own trigger, the way a macOS menu does. */
.contact-select-panel {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 20;
    display: flex;
    flex-direction: column;
    padding: 4px 0;
    background: #0f172a;
    border: 1px solid rgba(51,65,85,0.7);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.4);
    /* 8 rows fit the frame exactly; a longer list scrolls rather than
       running off the bottom of a short viewport. */
    max-height: 60vh;
    overflow-y: auto;
}
.contact-select-panel[hidden] { display: none; }

.contact-select-option {
    padding: 10px 16px;
    font-size: 14px;
    font-weight: 400;
    line-height: normal;
    color: #ffffff;
    opacity: 0.85;
    cursor: pointer;
}
/* The frame washes the selected row and inks it in the SECOND cyan. The
   keyboard-active row gets the same wash: aria-activedescendant is invisible,
   and a sighted keyboard user needs to see where they are. */
.contact-select-option.is-active,
.contact-select-option[aria-selected="true"] {
    background: var(--ct-pick-bg);
    opacity: 1;
}
.contact-select-option[aria-selected="true"] {
    color: var(--ct-cyan-pick);
    font-weight: 500;
}

.contact-submit {
    width: 100%;
    padding: 14px 28px;
    background: #00bfff;
    border: none;
    border-radius: 12px;
    color: var(--ct-cta-ink);
    font-size: 15px;
    font-weight: 600;
    line-height: normal;
    cursor: pointer;
    transition: background .2s;
}
/* Matches the landing .btn-audit hover; #0d121a on #33c7ff stays ~8.8:1. */
.contact-submit:hover:not(:disabled) { background: #33c7ff; }
.contact-submit:disabled { opacity: 0.65; cursor: progress; }

/* The live region. Empty at rest, so it occupies no space until it speaks. */
.contact-status {
    margin: 0;
    font-size: 14px;
    line-height: 1.55;
    color: var(--ct-muted);
}
.contact-status:empty { display: none; }
.contact-status--ok    { color: var(--ct-ok); }
.contact-status--error { color: #f87171; }

/* ── info side (187:311) ───────────────────────────────────────────── */

.contact-info {
    display: flex;
    flex-direction: column;
    gap: 40px;
    padding: 36px;
    background: var(--ct-surface);
    border: 1px solid rgba(51,65,85,0.7);
    border-radius: 16px;
}

.contact-info-head {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.contact-info-head h2 {
    margin: 0;
    font-size: 20px;
    font-weight: 600;
    line-height: 1.4;
    color: #ffffff;
}
.contact-info-sub {
    margin: 0;
    font-size: 15px;
    font-weight: 400;
    line-height: 1.55;
    color: var(--ct-muted);
}

.contact-info-block {
    display: flex;
    flex-direction: column;
    gap: 24px;
}
.contact-info-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.contact-eyebrow {
    margin: 0;
    font-size: 11px;
    font-weight: 600;
    line-height: normal;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--ct-cyan);
}

/* The frame draws the address as plain white text. It is a mailto: link
   because the page this replaced made it one, so the link is styled back
   down to the frame's appearance rather than the design being changed. */
.contact-info-value {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    line-height: normal;
    color: #ffffff;
}
/* :not(.btn) only to outscore base.css's `p a:not(.btn) { text-decoration:
   underline }`, which is 0-1-2 and would otherwise underline an address the
   frame draws plain. */
.contact-info-value a:not(.btn) {
    color: inherit;
    text-decoration: none;
}
.contact-info-value a:not(.btn):hover { color: var(--ct-cyan); }

.contact-status-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 14px;
    font-weight: 400;
    line-height: normal;
    color: #ffffff;
}
.contact-status-dot {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 4px;
    background: var(--ct-muted);
}
/* Colour follows the live overall state, exactly as the /status banner dot
   does. The label beside it carries the same information as text, so the
   row never depends on colour alone (WCAG 1.4.1). */
.contact-status-dot--operational { background: #4ade80; }
.contact-status-dot--degraded    { background: #fbbf24; }
.contact-status-dot--outage      { background: #f87171; }

.contact-resources {
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.contact-resources-h {
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    line-height: normal;
    color: var(--ct-label);
}
.contact-resource-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.contact-resource {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 14px;
    font-weight: 400;
    line-height: normal;
    color: var(--ct-muted);
}
.contact-resource-arrow {
    flex: none;
    color: var(--ct-cyan);
}
/* The frame underlines the label only, never the arrow. base.css underlines
   the whole of `li a:not(.btn)` at 0-1-2, so the anchor is cleared at 0-2-1
   and the underline put back on the label alone. */
.contact-resource:not(.btn) { text-decoration: none; }
.contact-resource-label { text-decoration: underline; text-underline-offset: 2px; }
.contact-resource:hover { color: #ffffff; }
.contact-resource:hover .contact-resource-arrow { color: var(--ct-cyan-pick); }

/* ── final CTA (187:335) ───────────────────────────────────────────── */

/* The frame leaves 160px between the form and the CTA box (80 of section
   padding either side) and 80px below it. main.container's u-padding-y
   already supplies 48 of that trailing 80. */
.contact-cta {
    padding: 160px 0 32px;
}
.contact-cta-box {
    width: 960px;
    max-width: 100%;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    padding: 48px 64px;
    background: var(--ct-surface);
    border: 1px solid rgba(51,65,85,0.7);
    border-radius: 16px;
    text-align: center;
}
.contact-cta-box h2 {
    margin: 0;
    font-size: 32px;
    font-weight: 700;
    line-height: normal;
    color: #ffffff;
}
.contact-cta-sub {
    max-width: 600px;
    margin: 0;
    font-size: 15px;
    font-weight: 400;
    line-height: normal;
    color: var(--ct-muted);
}
.contact-cta-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 15px 36px;
    border-radius: 12px;
    background: var(--ct-cyan);
    color: var(--ct-cta-ink);
    font-size: 15px;
    font-weight: 600;
    line-height: normal;
    text-decoration: none;
}
.contact-cta-btn:hover { background: #33c7ff; color: var(--ct-cta-ink); }

/* ── responsive (project convention: base.css collapses at 768px) ───── */

@media (max-width: 768px) {
    body.contact-page main.container { max-width: 1100px; }

    .contact { padding-top: 8px; }

    /* 427px + 629px will not fit a phone; the info card follows the form
       rather than leading it, so the thing the visitor came to do is first. */
    .contact-grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 40px;
    }
    .contact-info {
        width: 100%;
        max-width: 100%;
        padding: 28px 20px;
    }

    .contact-head h1 { font-size: 2.2rem; }
    .contact-hero-sub { font-size: 1rem; }

    .contact-cta { padding: 64px 0 8px; }
    .contact-cta-box { padding: 32px 20px; }
    .contact-cta-box h2 { font-size: 24px; }
}

/* iOS zooms the page in when a focused control's text is under 16px. The
   frame's 14px is kept everywhere it does not cost that, and only the
   controls themselves are bumped on small touch screens. */
@media (max-width: 480px) {
    /* Must repeat the .contact-form ancestor: the rule this overrides scores
       0-2-0 to outrank base.css, so a bare class here never applies. */
    .contact-form .contact-control { font-size: 16px; }
}
