/* ==========================================================================
   Dovetailed — shared foundation
   --------------------------------------------------------------------------
   Palette, reset, nav, buttons, footer, animations and section primitives.
   Everything here is identical on every page; page-specific sections stay in
   that page's own inline <style>.

   Why this file exists: the site was ten self-contained HTML files each
   carrying its own copy of the palette, nav and footer. CLAUDE.md said to
   extract "once we're at 4+ pages with churn" — we passed that some time ago,
   and a revamp that edits nav or palette by hand across ten files will drift.

   MIGRATION STATUS (2026-07-29): index.html uses this file. work.html,
   about.html, contact.html, privacy.html and writing/index.html still carry
   their own inline copies — visually identical, so nothing is broken, but
   they are a second source of truth until migrated. Do that next; it is
   mechanical (delete the shared rules, add the <link>).
   ========================================================================== */

:root {
    --color-walnut: #3D2B1F;
    --color-walnut-light: #5C4033;
    --color-teal: #2A9D8F;
    --color-teal-dark: #238379;
    --color-teal-light: #E6F5F3;
    --color-cream: #FAF7F2;
    --color-warm-white: #FFFDF9;
    --color-sand: #E8DFD0;
    --color-sand-light: #F2EDE4;
    --color-text: #2C2420;
    --color-text-muted: #7A6E65;
    --color-gold: #C49A3C;
    --color-gold-light: #F5EDD8;
    --font-display: 'DM Serif Display', Georgia, serif;
    --font-body: 'Plus Jakarta Sans', -apple-system, sans-serif;
}

*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html { scroll-behavior: smooth; }

body {
    font-family: var(--font-body);
    color: var(--color-text);
    background-color: var(--color-warm-white);
    line-height: 1.7;
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
}

/* ========== NAV ========== */
nav {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 100;
    padding: 1.25rem 2rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    transition: all 0.4s ease;
    background: transparent;
}

nav.scrolled {
    background: rgba(250, 247, 242, 0.92);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    box-shadow: 0 1px 0 rgba(61, 43, 31, 0.06);
}

.nav-logo {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    text-decoration: none;
    color: var(--color-walnut);
}

.nav-logo svg { width: 32px; height: 28px; }

.nav-logo-text {
    font-family: var(--font-display);
    font-size: 1.35rem;
    letter-spacing: -0.01em;
}

.nav-logo-text .ai-highlight,
.ai-highlight { color: var(--color-teal); }

.nav-right {
    display: flex;
    align-items: center;
    gap: 1.75rem;
}

.nav-link {
    font-family: var(--font-body);
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--color-walnut-light);
    text-decoration: none;
    transition: color 0.25s ease;
}

.nav-link:hover { color: var(--color-teal); }

/* Current-page marker. The unmigrated pages define this in their own inline
   CSS; it belongs here so migrated pages don't silently lose the highlight —
   which is exactly what happened when index.html and work.html moved to this
   stylesheet and the nav appeared to "go off" between pages. */
.nav-link.active,
.nav-cta.active { color: var(--color-teal); font-weight: 600; }

.nav-cta {
    font-family: var(--font-body);
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--color-teal-dark);
    text-decoration: none;
    padding: 0.6rem 1.4rem;
    border: 1.5px solid var(--color-teal);
    border-radius: 100px;
    transition: all 0.3s ease;
    letter-spacing: 0.01em;
}

.nav-cta:hover {
    background: var(--color-teal);
    color: white;
    transform: translateY(-1px);
}

/* ========== BUTTONS ========== */
.btn-primary {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--font-body);
    font-size: 0.95rem;
    font-weight: 600;
    color: white;
    background: var(--color-teal);
    padding: 0.85rem 2rem;
    border-radius: 100px;
    text-decoration: none;
    transition: all 0.3s ease;
    border: none;
    cursor: pointer;
    letter-spacing: 0.01em;
}

.btn-primary:hover {
    background: var(--color-teal-dark);
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(42, 157, 143, 0.25);
}

.btn-secondary {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--font-body);
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-walnut);
    background: transparent;
    padding: 0.85rem 1.75rem;
    border-radius: 100px;
    text-decoration: none;
    border: 1.5px solid var(--color-sand);
    transition: all 0.3s ease;
}

.btn-secondary:hover {
    border-color: var(--color-walnut-light);
    transform: translateY(-2px);
}

/* ========== SECTION PRIMITIVES ========== */
.section-label {
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: var(--color-teal);
    margin-bottom: 1rem;
}

.section-title {
    font-family: var(--font-display);
    font-size: clamp(2rem, 4vw, 2.8rem);
    line-height: 1.2;
    color: var(--color-walnut);
    margin-bottom: 1rem;
}

/* Decorative dovetail joint — the joinery metaphor, made visible */
.dovetail-divider {
    width: 100%;
    height: 40px;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 4px;
    padding: 0 2rem;
}

.dovetail-divider .tooth {
    width: 24px;
    height: 16px;
    background: var(--color-sand);
    clip-path: polygon(15% 0%, 85% 0%, 100% 100%, 0% 100%);
}

/* ========== FOOTER ========== */
footer {
    padding: 3rem 2rem 2.5rem;
    background: var(--color-walnut);
    color: rgba(255, 255, 255, 0.5);
}

.footer-cta {
    max-width: 1100px;
    margin: 0 auto 1.75rem;
    padding-bottom: 1.5rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    text-align: center;
    font-size: 0.95rem;
    color: rgba(255, 255, 255, 0.7);
}

.footer-cta a {
    color: var(--color-teal);
    text-decoration: none;
    font-weight: 600;
    border-bottom: 1.5px solid rgba(42, 157, 143, 0.5);
    padding-bottom: 1px;
    margin-left: 0.4rem;
    transition: border-color 0.25s ease;
}

.footer-cta a:hover { border-bottom-color: var(--color-teal); }

.footer-cta .footer-email {
    display: block;
    margin-top: 0.45rem;
    font-size: 0.85rem;
    color: rgba(255, 255, 255, 0.5);
}

.footer-cta .footer-email a {
    margin-left: 0;
    color: rgba(255, 255, 255, 0.85);
    border-bottom-color: rgba(255, 255, 255, 0.25);
    font-weight: 500;
}

.footer-cta .footer-email a:hover { border-bottom-color: rgba(255, 255, 255, 0.6); }

.footer-inner {
    max-width: 1100px;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
}

.footer-brand {
    font-family: var(--font-display);
    font-size: 1.1rem;
    color: rgba(255, 255, 255, 0.7);
}

.footer-brand .ai-highlight { color: var(--color-teal); }

.footer-tagline {
    font-size: 0.8rem;
    font-style: italic;
    color: rgba(255, 255, 255, 0.3);
}

.footer-right { font-size: 0.8rem; }

.footer-links { margin-bottom: 0.4rem; }

.footer-links a {
    color: rgba(255, 255, 255, 0.5);
    text-decoration: none;
    font-size: 0.8rem;
}

.footer-links a:hover { color: rgba(255, 255, 255, 0.75); }

/* ========== ANIMATIONS ========== */
@keyframes fadeUp {
    from { opacity: 0; transform: translateY(24px); }
    to   { opacity: 1; transform: translateY(0); }
}

.reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: all 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.reveal.visible {
    opacity: 1;
    transform: translateY(0);
}

/* Respect a user's reduced-motion preference — the reveal animation hides
   content until it fires, so it must never be the reason content is invisible. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
    .reveal { opacity: 1; transform: none; }
}

/* ========== RESPONSIVE ========== */
@media (max-width: 768px) {
    nav { padding: 1rem 1.25rem; }
    .nav-right { gap: 0.9rem; }
    .nav-link { font-size: 0.82rem; }
    .nav-cta { padding: 0.5rem 1rem; font-size: 0.8rem; }
    .footer-inner { flex-direction: column; text-align: center; }
}

/* Below ~480px the wordmark + three links + CTA no longer fit on one line —
   measured at 392px of content in a 375px viewport, which clipped the right
   edge of the "Get in touch" button. Drop the wordmark and keep the ///
   mark: it's distinctive on its own, and every nav destination stays
   reachable, which hiding the links would not have preserved. */
@media (max-width: 480px) {
    .nav-logo-text { display: none; }
    .nav-right { gap: 0.75rem; }
    .nav-link { font-size: 0.8rem; }
    .nav-cta { padding: 0.45rem 0.9rem; font-size: 0.78rem; }
}

/* Back-route from an article to the writing index — added 2026-08-19 when
   Writing gave its nav slot to Care. Sits inside each article page cta-strip. */
.cta-back { margin-top: 1.5rem; font-size: 0.92rem; }
.cta-back a { color: rgba(255, 255, 255, 0.75); text-decoration: underline; }
.cta-back a:hover { color: #ffffff; }

/* In-copy links — teal, not browser blue. Scoped to content containers so the
   nav, buttons, footer and cta-strips keep their own colours. Added 2026-08-19;
   before this, no rule anywhere styled a bare <a> in body copy. */
.content a, .article a, .careloop a, .running-services a, .metrics-method a {
    color: var(--color-teal-dark);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.content a:hover, .article a:hover, .careloop a:hover,
.running-services a:hover, .metrics-method a:hover {
    color: var(--color-teal);
}

/* Journey buttons — added 2026-08-19. .btn-ghost is the outline button for the
   dark walnut cta-strips (btn-secondary is walnut-on-cream and vanishes there);
   .cta-actions rows two buttons in a strip. The chain: home → /work (In action)
   → /care → /about → contact. */
.btn-ghost {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--font-body);
    font-size: 0.95rem;
    font-weight: 600;
    color: white;
    background: transparent;
    padding: 0.85rem 2rem;
    border-radius: 100px;
    text-decoration: none;
    transition: all 0.3s ease;
    border: 1px solid rgba(255, 255, 255, 0.45);
    cursor: pointer;
    letter-spacing: 0.01em;
}
.btn-ghost:hover { border-color: white; transform: translateY(-2px); }

.cta-actions {
    display: flex;
    gap: 1rem;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
}
.hero-sub a { color: var(--color-teal-dark); text-decoration: underline; text-underline-offset: 2px; }
.hero-sub a strong { color: var(--color-teal-dark); }
.hero-sub a:hover, .hero-sub a:hover strong { color: var(--color-teal); }

/* Above-the-fold journey button in page headers — same outline treatment as
   the hero's "See it in action". Added 2026-08-19. */
.header-actions { margin-top: 1.9rem; display: flex; gap: 1rem; flex-wrap: wrap; }

/* ========== CONVERSATION THREAD ==========
   Shared 2026-08-22. Lived inline on index.html as the conversation player;
   work.html carried a second, different-looking sample (.chat / .bubble). Two
   homes, one component — the framing is now identical on both pages, and the
   only page-specific part left is the section layout around it.

   Section-level layout (index's .conversation grid, work's article column)
   stays inline on the page that owns it. */
.thread {
    background: var(--color-cream);
    border: 1px solid var(--color-sand);
    border-radius: 14px;
    overflow: hidden;
    max-width: 440px;
    width: 100%;
    justify-self: center;
}

/* Header — messaging-app shape, Dovetailed's palette. Deliberately NOT
   WhatsApp's mark or green: the idiom is recognisable without borrowing
   someone's trademark, and their green fights our teal. */
.thread-head {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.85rem 1.1rem;
    background: var(--color-warm-white);
    border-bottom: 1px solid var(--color-sand);
}

.thread-avatar {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--color-teal-light);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.thread-avatar svg { width: 17px; height: 14px; }

.thread-name {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--color-walnut);
    line-height: 1.3;
}

.thread-status {
    font-size: 0.72rem;
    color: var(--color-text-muted);
    display: flex;
    align-items: center;
    gap: 0.35rem;
    line-height: 1.3;
}

.thread-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-teal);
    flex-shrink: 0;
}

/* No min-height. The old player reserved 430px so the card didn't grow and
   shrink as bubbles were typed in; nothing is typed in any more, so the log is
   exactly as tall as its messages on every page. */
.thread-log {
    padding: 1.25rem 1.1rem;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

/* ---- Bubbles ---- */
.msg { max-width: 84%; }
.msg.them { align-self: flex-start; }
.msg.us { align-self: flex-end; }

.msg-bubble {
    padding: 0.65rem 0.9rem;
    border-radius: 14px;
    font-size: 0.875rem;
    line-height: 1.55;
    white-space: pre-line;
}

/* Patient */
.msg.them .msg-bubble {
    background: var(--color-warm-white);
    border: 1px solid var(--color-sand);
    border-bottom-left-radius: 4px;
}

/* Assistant */
.msg.us .msg-bubble {
    background: var(--color-teal-light);
    border: 1px solid rgba(42, 157, 143, 0.18);
    border-bottom-right-radius: 4px;
}

.msg-bubble em {
    font-style: normal;
    font-weight: 600;
    color: var(--color-walnut);
}

/* Optional. The component must read correctly without it — work.html's samples
   carry no times, because inventing timestamps for an illustration would be
   inventing detail. */
.msg-time {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.68rem;
    color: var(--color-text-muted);
}

.msg.us .msg-time { text-align: right; }

/* The decline. A hairline, not a highlight — it should feel deliberate,
   not decorated. */
.msg.decline .msg-bubble { border-left: 2px solid var(--color-teal); }

/* ---- Foot ---- */
.thread-foot {
    padding: 0.8rem 1.1rem;
    border-top: 1px solid var(--color-sand);
    background: var(--color-warm-white);
}

.thread-note {
    font-size: 0.7rem;
    line-height: 1.4;
    color: var(--color-text-muted);
}

/* ---- Scroll reveal ----
   Default is VISIBLE. The page script adds .armed to the thread to hide the
   messages, then adds .shown to each one as it scrolls into view. That ordering
   is the whole safety story: if the script never runs, or errors, or the
   visitor has reduced motion on, every message is still on screen. This site
   has already shipped the opposite bug once — see the .reveal note above. */
.thread.armed .msg {
    opacity: 0;
    transform: translateY(10px);
}

.thread.armed .msg.shown {
    opacity: 1;
    transform: none;
    transition: opacity 0.45s cubic-bezier(0.22, 1, 0.36, 1),
                transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Belt and braces: the script already refuses to arm under reduced motion, so
   this only matters if the preference is turned on after arming. */
@media (prefers-reduced-motion: reduce) {
    .thread.armed .msg { opacity: 1; transform: none; }
    .thread.armed .msg.shown { transition: none; }
}
