/* ============================================================
   Reach out — the typewriter correspondence page.
   A 3D typewriter (typewriter-contact.js) types the studio's
   questions in red ink on an aged sheet; the visitor answers in
   black on their own keyboard. Light gray-white gradient page —
   the red identity now lives in the ribbon ink.

   Progressive enhancement contract:
   - default (no JS / no WebGL):  .reachout-fallback rows visible
   - html.tw-3d:                  3D stage + corners visible,
                                  fallback becomes screen-reader-only
   - html.tw-fallback:            explicit fallback (phones, coarse
                                  pointers, WebGL failure)
   ============================================================ */

@font-face {
    font-family: 'Geist Mono';
    src: url('geist-font-v1.7.2/geist-font/GeistMono/webfonts/GeistMono-Regular.woff2') format('woff2');
    font-weight: 400;
    font-display: swap;
}

body {
    /* echoes the in-scene backdrop so load-in and fallback match —
       a touch more contrast (whiter centre, deeper edges) but still subtle */
    background: radial-gradient(ellipse 92% 82% at 50% 46%,
        #f8f8f6 0%, #e5e5e1 36%, #bcbcb6 66%, #888883 100%) fixed;
}

html.tw-3d body, html.tw-mobile body { overflow: hidden; }   /* single-viewport experience */

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

/* The nav stays transparent here (the rest of the site now has a solid nav bar): it floats
   over the typewriter scene's gradient instead of laying a flat strip across it. */
header { background: transparent; }

/* ---- 3D stage --------------------------------------------------- */
#tw-stage {
    position: fixed; inset: 0; z-index: 1;
    display: none;
    pointer-events: none;        /* keyboard-driven; links stay clickable */
}
#tw-stage canvas { display: block; width: 100%; height: 100%; }
html.tw-3d #tw-stage, html.tw-mobile #tw-stage { display: block; }

/* ---- mobile conversation panel (lower half) ---------------------- */
#tw-panel { display: none; }
html.tw-mobile #tw-panel {
    display: flex;
    flex-direction: column;
    position: fixed; left: 0; right: 0; bottom: 0;
    height: 47vh; z-index: 40;
    background: #fbfbf9;
    border-top-left-radius: 20px; border-top-right-radius: 20px;
    box-shadow: 0 -14px 40px rgba(0,0,0,.22);
    padding: 20px 20px calc(16px + env(safe-area-inset-bottom));
    /* pops up from the bottom on load */
    animation: tw-panel-pop .6s cubic-bezier(.2,.9,.25,1) both;
}
@keyframes tw-panel-pop {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
    html.tw-mobile #tw-panel { animation: none; }
}
#tw-log {
    flex: 1 1 auto; overflow-y: auto;
    font-family: var(--font-mono, 'Geist Mono', ui-monospace, monospace);
    font-size: 17px; line-height: 1.55;
    -webkit-overflow-scrolling: touch;
}
#tw-log .tw-line { min-height: 1.55em; white-space: pre-wrap; word-break: break-word; }
#tw-log .ink-s { color: #b71f25; }        /* studio ribbon red */
#tw-log .ink-u { color: #241c15; }        /* visitor black */

#tw-entry { flex: 0 0 auto; padding-top: 12px; }
#tw-options { display: flex; flex-wrap: wrap; gap: 8px; }
.tw-chip {
    font-family: var(--font-mono, 'Geist Mono', monospace);
    font-size: 15px; letter-spacing: .01em;
    padding: 11px 16px;
    background: #f0efe9; color: #241c15;
    border: 1px solid rgba(0,0,0,.16); border-radius: 999px;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
/* hover inverts the chip (same motif as the consent buttons); :active stays a shade.
   The send chip is styled exactly like the other chips (the red version is gone). */
.tw-chip:hover { background: #241c15; color: #f0efe9; border-color: #241c15; }
.tw-chip:active { background: #e4e2da; color: #241c15; }

#tw-form { display: flex; gap: 8px; }
#tw-form[hidden] { display: none; }
#tw-input {
    flex: 1 1 auto;
    font-family: var(--font-mono, 'Geist Mono', monospace);
    font-size: 16px;                        /* 16px keeps iOS from zooming */
    padding: 12px 14px;
    border: 1px solid rgba(0,0,0,.22); border-radius: 12px;
    background: #fff; color: #241c15;
}
#tw-form button {
    flex: 0 0 auto;
    width: 48px; border-radius: 12px;
    background: #f0efe9; color: #241c15;             /* matches the chips, not red */
    border: 1px solid rgba(0,0,0,.16);
    font-size: 20px;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
#tw-form button:hover { background: #241c15; color: #f0efe9; border-color: #241c15; }
#tw-form button:active { background: #e4e2da; color: #241c15; }

/* Inline validation — replaces the browser's native email bubble (the form is novalidate).
   Ribbon red + Geist Mono, a red circled "!" to the left; slides in above the input. */
.tw-error {
    display: flex; align-items: center; gap: 8px;
    margin-bottom: 10px;
    font-family: var(--font-mono, 'Geist Mono', monospace);
    font-size: 14px; line-height: 1.4;
    color: #b71f25;
    animation: tw-error-in .26s cubic-bezier(.2,.9,.25,1) both;
}
.tw-error::before {
    content: "!";
    flex: 0 0 auto;
    display: inline-grid; place-items: center;
    width: 18px; height: 18px;
    border: 1.5px solid #b71f25; border-radius: 50%;
    font-size: 11px; font-weight: 700; line-height: 1;
}
@keyframes tw-error-in {
    from { opacity: 0; transform: translateY(5px); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) { .tw-error { animation: none; } }

/* ---- desktop Q&A panel (left, vertically centered) ---------------- */
/* The current question in Geist (sans), the answers as mono chips or an
   underlined input with a pill arrow — same conversation the machine is
   typing, made clickable. Only exists in tw-3d mode. */
/* --nav-edge = the header's content edge: it centres inside max-width 120rem
   with 5rem padding, so this formula tracks the nav's start/end exactly (the
   corner buttons + panel align to it). --desk-lift top-anchors the panel so
   the current question stays put while the answers below it grow/shrink. */
:root { --nav-edge: calc((100vw - 120rem) / 2 + var(--gutter, 2.5rem)); --desk-lift: 176px; }
#tw-desk { display: none; }
html.tw-3d #tw-desk {
    display: block;
    position: fixed; z-index: 20;
    left: var(--nav-edge);
    top: 50%; transform: translateY(calc(-1 * var(--desk-lift)));
    width: min(31vw, 430px);
}
/* Question stack — fixed-height stage so the widgets below never jump.
   The current line is anchored to the stack's bottom and types in live;
   a retired line gets translated to the top (JS measures the exact offset),
   scaled down and blurred; the one before that fades out fully. */
#tw-desk-qs {
    position: relative;
    height: 186px;
    margin: 0 0 24px;
}
#tw-desk-qs .tw-q {
    position: absolute; left: 0; right: 0; bottom: 0;
    margin: 0;
    font-family: var(--font-sans, 'Geist', sans-serif);
    font-weight: 400;
    font-size: clamp(22px, 1.9vw, 32px);
    line-height: 1.3;
    letter-spacing: -0.01em;
    color: #141414;
    transform-origin: left bottom;         /* grows/settles upward, never into the widgets */
    transition: transform .48s cubic-bezier(.22, .9, .3, 1), opacity .48s ease, filter .48s ease;
    will-change: transform, opacity, filter;
}
/* Focus choreography: the line TYPES oversized (it owns the moment), then
   settles down to true size right as the answers rise in below — the eye
   follows the release. */
#tw-desk-qs .tw-q.is-current { transform: scale(1.1); }
#tw-desk-qs .tw-q.is-current.is-settled { transform: scale(1); }
/* Retired line: full ink, just out of focus — presence without competition. */
#tw-desk-qs .tw-q.is-past {
    filter: blur(5px);
    pointer-events: none;
}
#tw-desk-qs .tw-q.is-gone {
    opacity: 0;
    filter: blur(6px);
    pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
    #tw-desk-qs .tw-q { transition: none; }
}

/* Typing cursor — a solid block riding the letter being struck. */
#tw-desk-qs .tw-cur {
    display: inline-block;
    width: .5em; height: .95em;
    margin-left: .08em;
    background: currentColor;
    transform: translateY(.1em);
    transition: opacity .22s ease;
}
#tw-desk-qs .tw-cur.is-done { opacity: 0; }
/* once the line is fully typed, the cursor stays and breathes at its end */
#tw-desk-qs .tw-cur.is-blinking { animation: tw-cur-blink 1.1s ease-in-out infinite; }
@keyframes tw-cur-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
/* Scramble letter — the REAL letter is an invisible ghost that owns the
   width; the cycling glyph is painted on top. Neighbours never shift. */
#tw-desk-qs .tw-scr { position: relative; display: inline-block; }
#tw-desk-qs .tw-scr__ghost { visibility: hidden; }
#tw-desk-qs .tw-scr__live { position: absolute; left: 0; top: 0; }

/* Answer zone flows below the top-anchored question — no fixed height needed
   now (the question can't be shoved), so open-text steps get a tall textarea
   and chip steps stay compact without either one moving the question. */
#tw-desk-a { min-height: 40px; }
#tw-desk-opts { display: flex; flex-wrap: wrap; gap: 10px; }
/* Ghost chip — the studio email + copy glyph. Transparent, white border,
   white text; hover only darkens the ink, never inverts or fills. */
#tw-desk-opts .tw-chip--ghost {
    display: inline-flex; align-items: center; gap: 9px;
    background: transparent;               /* fully transparent at rest */
    color: #fff; border-color: #fff;
}
#tw-desk-opts .tw-chip--ghost svg {
    width: 15px; height: 15px; flex: 0 0 auto;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
/* hover just adds a light dark tint — text + border stay white */
#tw-desk-opts .tw-chip--ghost:hover,
#tw-desk-opts .tw-chip--ghost:active {
    background: rgba(0, 0, 0, 0.22);
    color: #fff; border-color: #fff;
}
/* IN: fade + rise, springy enough to be felt (chips stagger via JS delay).
   OUT: fade + sink back down. */
#tw-desk-opts, #tw-desk-form { transition: opacity .24s ease, transform .24s ease; }
#tw-desk-opts.is-hiding, #tw-desk-form.is-hiding {
    opacity: 0; transform: translateY(14px);
    pointer-events: none;
    animation: none;                       /* fill-forwards rise-in must not pin opacity */
}
#tw-desk-opts .tw-chip { animation: tw-desk-in .5s cubic-bezier(.18, .9, .22, 1.06) both; }
#tw-desk-form:not([hidden]) { animation: tw-desk-in .5s cubic-bezier(.18, .9, .22, 1.06) both; animation-delay: 60ms; }
@media (prefers-reduced-motion: reduce) {
    #tw-desk-opts .tw-chip, #tw-desk-form:not([hidden]) { animation: none; }
}
/* standard chips match the mobile sheet exactly (.tw-chip base styles) */
#tw-desk-form { display: block; }
#tw-desk-form[hidden] { display: none; }
#tw-desk-input, #tw-desk-textarea {
    display: block; width: 100%;
    font-family: var(--font-mono, 'Geist Mono', monospace);
    font-size: 16px; letter-spacing: .01em; line-height: 1.5;
    padding: 8px 2px 12px;
    border: 0; border-bottom: 1px solid #141414; border-radius: 0;
    background: transparent; color: #241c15;
    outline: none;
}
#tw-desk-input[hidden], #tw-desk-textarea[hidden] { display: none; }
#tw-desk-input::placeholder, #tw-desk-textarea::placeholder { color: rgba(20,20,20,.4); }
/* the "open text" field — 4 lines, taller, with a drag handle like the ref */
#tw-desk-textarea {
    min-height: calc(4 * 1.5em + 20px);
    resize: vertical;
}
#tw-desk-form button {
    display: grid; place-items: center;
    margin: 20px 0 0 auto;
    width: 58px; height: 36px;
    border-radius: 999px;
    background: #fbfbf9; color: #141414;
    border: 1px solid rgba(0,0,0,.12);
    box-shadow: 0 1px 5px rgba(0,0,0,.08);
    cursor: pointer;
    transition: background .2s ease, color .2s ease, border-color .2s ease;
}
#tw-desk-form button:hover { background: #241c15; color: #fbfbf9; border-color: #241c15; }
#tw-desk-form button svg {
    width: 18px; height: 18px;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
}
@keyframes tw-desk-in {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: none; }
}

/* ---- corner furniture -------------------------------------------- */
.tw-corner {
    position: fixed; z-index: 30;
    display: none;
    font-family: var(--font-pixel);
    font-size: 12px; letter-spacing: .06em;
    color: #111;
}
html.tw-3d .tw-corner { display: flex; }
/* mobile: WhatsApp pinned top-left, the sound capsule top-right — its top
   (sound-off) icon rides parallel to the WhatsApp circle */
html.tw-mobile .tw-corner--wa { display: flex; top: 74px; left: 20px; bottom: auto; }
html.tw-mobile .tw-corner--alt { display: flex; top: 74px; right: 20px; bottom: auto; }
.tw-corner a, .tw-corner button {
    color: #111;
    background: none; border: none; padding: 0 0 2px;
    font: inherit; letter-spacing: inherit;
    border-bottom: 1px solid rgba(0,0,0,.35);
    cursor: pointer;
}
.tw-corner a:hover, .tw-corner button:hover { border-bottom-color: #111; }

/* aligned to the nav's content edges (WhatsApp's left = "FloriumStudio" left,
   the sound capsule's right = "Reach out" right) */
.tw-corner--wa {
    left: var(--nav-edge); bottom: 24px;
    align-items: center; gap: 10px;
}
.tw-corner--alt {
    right: var(--nav-edge); bottom: 24px;
    flex-direction: column; align-items: flex-end; gap: 10px;
    text-align: right;
}

/* ---- WhatsApp — round icon button (Figma "whatsapp") ------------- */
.tw-corner a.tw-wa-btn {
    position: relative;
    display: grid; place-items: center;
    width: 52px; height: 52px;
    border-radius: 50%;
    background: #111; color: #fff;
    border: 0; padding: 0;                    /* overrides the old underlined-text style */
    transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}
/* hover inverts the button (no scale): white circle, black glyph, a hairline
   ring so it doesn't melt into the light backdrop */
.tw-corner a.tw-wa-btn:hover {
    background: #fff; color: #111;
    box-shadow: inset 0 0 0 1px rgba(0,0,0,.2);
    border: 0;
}
.tw-wa-btn svg { width: 26px; height: 26px; display: block; }

/* ---- Sound — vertical capsule toggle (Figma "sound off on") ------ */
/* One white icon set; the knob is a circle that INVERTS whatever sits under
   it (backdrop-filter), so over the black capsule it reads white and the
   icon it covers flips to black — no second icon colourway needed. */
.tw-corner button.tw-sound {
    position: relative;
    width: 52px; height: 100px;
    border-radius: 275px;
    background: #111;
    border: 0; padding: 0;
    cursor: pointer;
}
.tw-corner button.tw-sound:hover { border: 0; }
.tw-sound__icon {
    position: absolute; left: 50%;
    width: 22px; height: 22px;
    transform: translateX(-50%);
    color: #fff;
    fill: none; stroke: currentColor; stroke-width: 2;
    stroke-linecap: round; stroke-linejoin: round;
    pointer-events: none;
}
.tw-sound__icon--off { top: 14px; }
.tw-sound__icon--on { bottom: 14px; }
.tw-sound__knob {
    position: absolute; left: 4px;
    top: 52px;                                 /* sound ON — resting on the on-icon */
    width: 44px; height: 44px;
    border-radius: 50%;
    -webkit-backdrop-filter: invert(1);
    backdrop-filter: invert(1);
    transition: top .28s cubic-bezier(.22, 1, .36, 1);
    pointer-events: none;
}
.tw-sound.is-off .tw-sound__knob { top: 4px; } /* sound OFF — over the speaker-x */
/* no backdrop-filter support: solid white knob + flip the covered icon by hand */
@supports not ((backdrop-filter: invert(1)) or (-webkit-backdrop-filter: invert(1))) {
    .tw-sound__knob { background: #fff; }
    .tw-sound:not(.is-off) .tw-sound__icon--on { color: #111; }
    .tw-sound.is-off .tw-sound__icon--off { color: #111; }
}

/* (the green availability dot is gone — off-hours only swap the tooltip text) */

/* ---- fallback: the editorial contact rows ------------------------ */
/* Visible by default. In 3D mode it stays in the accessibility tree
   (screen readers get real links) but leaves the screen. */
.reachout-fallback {
    max-width: 1100px;
    margin: 0 auto;
    padding: 180px 32px 120px;
}
html.tw-3d .reachout-fallback,
html.tw-mobile .reachout-fallback {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

.reachout-label {
    font-family: var(--font-sans);
    font-size: 24px; line-height: 32px;
    margin-bottom: 18px;
}
.reachout-intro {
    font-family: var(--font-sans);
    font-size: 20px; line-height: 30px;
    max-width: 620px;
    margin-bottom: 90px;
    color: rgba(0,0,0,.8);
}

.reachout-channels { display: block; }

.reachout-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 40px;
    border-top: 2px solid #111;
    padding: 26px 0 30px;
}
.reachout-row:last-child { border-bottom: 2px solid #111; }

.reachout-row__label {
    font-family: var(--font-serif);
    font-weight: 400;
    font-size: clamp(40px, 6.5vw, 96px);
    line-height: 1;
}

.reachout-row__to {
    display: inline-flex;
    align-items: center;
    gap: 18px;
    flex-shrink: 0;
    font-family: var(--font-sans);
    font-size: 20px;
    line-height: 1;
    white-space: nowrap;
}

.reachout-row__to svg {
    width: 28px; height: 28px;
    flex-shrink: 0;
    stroke: #111;
    stroke-width: 2;
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
}

@media (max-width: 640px) {
    .reachout-fallback { padding-top: 140px; }
    .reachout-row { flex-direction: column; align-items: flex-start; gap: 14px; }
}
