/* ==========================================================================
   Tech Duchess re-skin — loads after style.css and wins the cascade.
   Locked palette (sharpened 02):
     Violet   #28083E  brand spine        Magenta #B8005E  the single raised voice
     Charcoal #1A1525  secondary base     Cream   #F8F4FF  text on dark
     Lilac    #C77DFF  decorative only
   Supporting: violet-deep #190428, violet-darker #110319,
   cream alphas .65/.4/.18/.08, magenta glow rgba(184,0,94,.45)
   Faces: Playfair Display (display/wordmark), Inter (body), ui-monospace (labels)
   ========================================================================== */

:root {
    --td-violet: #28083E;
    --td-violet-deep: #190428;
    --td-violet-darker: #110319;
    --td-charcoal: #1A1525;
    --td-magenta: #B8005E;
    --td-cream: #F8F4FF;
    --td-lilac: #C77DFF;
    --td-cream-mute: rgba(248, 244, 255, 0.65);
    --td-cream-dim: rgba(248, 244, 255, 0.4);
    --td-cream-faint: rgba(248, 244, 255, 0.18);
    --td-line: rgba(248, 244, 255, 0.08);
    --td-magenta-glow: rgba(184, 0, 94, 0.45);
    --td-font-display: 'Playfair Display', Georgia, serif;
    --td-font-body: 'Inter', system-ui, -apple-system, sans-serif;
    --td-font-mono: ui-monospace, 'SF Mono', Menlo, monospace;

    /* Template token overrides */
    --color-primary: var(--td-magenta);
    --color-primary-alt: rgba(184, 0, 94, 0.85);
    --color-primary-2nd: var(--td-magenta);
    --color-primary-3rd: var(--td-lilac);
    --color-primary-4th: var(--td-lilac);
    --color-secondary: var(--td-violet-darker);
    --color-gray: var(--td-cream-mute);
    --color-gray-2: var(--td-charcoal);
    --color-subtitle: var(--td-lilac);
    --background-color-1: rgba(40, 8, 62, 0.34);
    --background-color-2: var(--td-violet-darker);
    --background-color-3: var(--td-violet-deep);
    --background-color-4: var(--td-violet);
    --color-card: var(--td-violet-deep);
    --gradient-box: linear-gradient(to right, var(--td-violet), var(--td-magenta));
    --gradient-one: linear-gradient(to right bottom, var(--td-magenta), var(--td-violet));
    --gradient-two: linear-gradient(to right, var(--td-magenta), var(--td-violet));
    --gradient-three: linear-gradient(to right, var(--td-violet-darker), var(--td-violet));
    --text-gradient-one: linear-gradient(to right, var(--td-magenta), var(--td-lilac));
    --color-heading: var(--td-cream);
    --color-body: var(--td-cream-mute);
    --color-dark: var(--td-charcoal);
    --color-text-1: var(--td-cream);
    --color-border-white: var(--td-cream-faint);

    --font-primary: var(--td-font-display);
    --font-secondary: var(--td-font-body);
}

/* --------------------------------------------------------------------------
   Base surfaces & type
   -------------------------------------------------------------------------- */
body {
    background: var(--td-violet-darker);
    font-family: var(--td-font-body);
}

h1, h2, h3, h4, .title {
    font-family: var(--td-font-display);
    font-weight: 500;
}

/* Editorial register: no gamer-caps on big titles */
.section-head .title,
.edu-title,
.portfolio-card-title {
    text-transform: none;
    letter-spacing: 0;
}

/* Small section markers keep the mono-cap treatment: full-opacity, real weight */
.custom-title {
    font-family: var(--td-font-mono);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--td-lilac);
}

/* Magenta accents inside big titles */
.td-title-accent {
    font-style: italic;
    font-weight: 400;
    color: var(--td-magenta);
}

/* --------------------------------------------------------------------------
   Wordmark (locked): "Tech" Playfair 500 roman cream, "Duchess" italic 400 magenta.
   Never underline, shadow, gradient or stretch.
   -------------------------------------------------------------------------- */
.td-banner-wordmark,
.td-card-wordmark,
.td-footer-wordmark a {
    font-family: var(--td-font-display);
    font-weight: 500;
    font-style: normal;
    color: var(--td-cream);
    text-decoration: none;
}

.td-banner-wordmark em,
.td-card-wordmark em,
.td-footer-wordmark a em {
    font-style: italic;
    font-weight: 400;
    color: var(--td-magenta);
}

/* --------------------------------------------------------------------------
   Banner: brand treatment (placeholder until a hero photo exists)
   -------------------------------------------------------------------------- */
.tmp-breadcrumb-image {
    height: 440px;
    overflow: hidden;
    /* template ships z-index:-1, which makes anything inside unclickable
       (the 404 page puts a button in the banner) */
    z-index: 0;
}

.bg_image--2 {
    background-image:
        radial-gradient(ellipse 65% 80% at 78% 30%, var(--td-magenta-glow), transparent 62%),
        radial-gradient(ellipse 50% 70% at 15% 85%, rgba(199, 125, 255, 0.16), transparent 60%),
        linear-gradient(160deg, var(--td-violet) 0%, var(--td-violet-deep) 55%, var(--td-violet-darker) 100%);
    background-size: cover;
}

.td-banner-inner {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0 20px;
}

.td-banner-eyebrow {
    font-family: var(--td-font-mono);
    font-weight: 700;
    font-size: 13px;
    letter-spacing: 0.28em;
    text-transform: uppercase;
    color: var(--td-lilac);
    margin-bottom: 18px;
}

.td-banner-wordmark {
    font-size: clamp(52px, 8vw, 96px);
    line-height: 1.05;
    margin-bottom: 20px;
}

.td-banner-frame {
    font-family: var(--td-font-display);
    font-style: italic;
    font-size: 17px;
    color: var(--td-cream-mute);
    letter-spacing: 0.06em;
    margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   Profile card
   -------------------------------------------------------------------------- */
.td-card-wordmark {
    font-size: 30px;
}

.tmp-contact-about-inner .subtitle {
    font-family: var(--td-font-mono);
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 0.08em;
    color: var(--td-lilac);
}

.tmp-contact-about-inner .info-box .phone,
.tmp-contact-about-inner .info-box .mail {
    font-family: var(--td-font-body);
    overflow-wrap: anywhere;
    font-size: 14px;
}

/* --------------------------------------------------------------------------
   Profile card stays a centred column at EVERY width.
   The template turns the card into a flex row from 576px to 1199px and
   force-left-aligns .content, which threw the wordmark, the subtitle, the
   live line and the social row 230px to 330px right of centre on a laptop,
   and packed the icons hard left on a phone (Duchess flagged it 2026-08-22).
   -------------------------------------------------------------------------- */
.tmp-contact-about-inner,
.tmp-contact-about-inner .content {
    display: block;
    text-align: center;
}

/* Only the CONTENT loses its left padding. Zeroing it on the card too would
   leave the card padded 30px right and 0 left, shifting everything inside it
   half that off centre. */
.tmp-contact-about-inner .content {
    padding-left: 0;
}

.tmp-contact-about-inner .title-area,
.tmp-contact-about-inner .description,
.tmp-contact-about-inner .info-box {
    text-align: center;
}

/* Bootstrap's justify-content-center utility is !important, and the template
   answers with its own !important at phone widths; this needs to outrank
   both, so it carries the extra class and the flag. */
.tmp-contact-about-inner .social-link.td-social-accordion {
    display: flex;
    flex-wrap: wrap;
    justify-content: center !important;
    gap: 8px;
}

/* All seven marks stay on ONE line in the sidebar (Duchess, 2026-08-22: two
   rows read as a fault). Seven 40px chips need 328px and the column offers
   219px at 1400 rising to 304px at 1920, so the chip size is derived from the
   column itself with a container query: 40px wherever it fits, shrinking only
   as far as it must. That beats a media-query guess because the column width
   is not monotonic with the viewport — the template changes its side padding
   at 1600, so 1600 gives LESS room (224px) than 1500 (244px).
   nowrap makes the single line a guarantee rather than a calculation. */
@media (min-width: 1400px) {
    .tmp-contact-about-inner .social-area {
        container-type: inline-size;
    }

    .tmp-contact-about-inner .social-link.td-social-accordion {
        flex-wrap: nowrap;
        gap: 3px;
    }

    .tmp-contact-about-inner .td-social-accordion a.td-social {
        --td-chip: min(40px, (100cqi - 15px) / 6);
        width: auto;
        height: var(--td-chip);
        min-width: var(--td-chip);
        max-width: var(--td-chip);
        padding: 0 calc((var(--td-chip) - 15px) / 2);
        overflow: hidden;
    }

    /* A true accordion: the hovered pill takes the room it needs to say its
       name and the others give way, so the row never breaks onto a second
       line. Dropping Facebook made this comfortable — six pills instead of
       seven, and the widest label ("Instagram") now fits inside the card at
       every width from 1400px up. */
    .tmp-contact-about-inner .td-social-accordion:hover a.td-social,
    .tmp-contact-about-inner .td-social-accordion:focus-within a.td-social {
        min-width: 24px;
    }

    .tmp-contact-about-inner .td-social-accordion a.td-social:hover,
    .tmp-contact-about-inner .td-social-accordion a.td-social:focus-visible {
        min-width: 0;
        max-width: 200px;
        flex-shrink: 0;
        padding: 0 12px;
        gap: 8px;
    }
}

.tmp-contact-about-inner .button-area-banner-one .btn-text {
    white-space: nowrap;
}

/* Portrait tile: the photo, clean. No ring — the brand's magenta avatar ring
   is specced for platforms that crop avatars to a circle; on a square web tile
   it just draws a circle across her face (Duchess flagged it 2026-08-20).
   Violet base shows behind the photo while the image loads. */
.td-portrait-tile {
    position: relative;
    aspect-ratio: 1 / 1;
    border-radius: 14px;
    background: linear-gradient(150deg, var(--td-violet) 0%, var(--td-violet-darker) 100%);
    overflow: hidden;
}

/* Between 992px and 1399px the profile column goes full width, so an
   unconstrained square tile grew to ~950px while the template capped the
   photo at max-width:300px — the photo then filled a third of its frame.
   Cap the tile and lift the template's cap (selector carries one class more
   than `.tmp-contact-about-inner .thumbnail img`, so no !important needed). */
.tmp-contact-about-inner .thumbnail.td-portrait-tile {
    max-width: 340px;
    margin-left: auto;
    margin-right: auto;
}

.tmp-contact-about-inner .thumbnail.td-portrait-tile img {
    display: block;
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    object-fit: cover;
    border-radius: 14px;
}

/* --------------------------------------------------------------------------
   Tabs, buttons, small components
   -------------------------------------------------------------------------- */
.tab-navigation-button .nav-link.tmp-nav {
    font-family: var(--td-font-mono);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    font-size: 13px;
    /* Centred explicitly: "What to expect" wrapped to two lines and the
       second line sat left, which read as a misalignment (Duchess,
       2026-08-23). The label is one word now, but a centred rule means a
       future long label cannot reintroduce it. */
    text-align: center;
}

/* Theme tabs: Light / Dark / System segmented pill (21st.dev theme-tabs,
   ported to the brand). The track whispers; the sliding pill is violet;
   only the active icon gets full-opacity cream. */
.td-theme-tabs-item {
    display: flex;
    justify-content: center;
    margin-top: 14px;
}

.td-theme-tabs {
    position: relative;
    display: inline-flex;
    gap: 2px;
    padding: 4px;
    border: 1px solid var(--td-cream-faint);
    border-radius: 999px;
    background: rgba(26, 21, 37, 0.45);
}

.td-theme-tabs__pill {
    position: absolute;
    top: 4px;
    left: 4px;
    width: 32px;
    height: 32px;
    border-radius: 999px;
    background: var(--td-violet);
    border: 1px solid rgba(199, 125, 255, 0.35);
    pointer-events: none;
}

.td-theme-tabs.is-ready .td-theme-tabs__pill {
    transition: transform 0.3s cubic-bezier(0.34, 1.4, 0.4, 1);
}

.td-theme-tab {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--td-cream-dim);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    transition: color 0.2s ease;
}

.td-theme-tab:hover {
    color: var(--td-lilac);
}

.td-theme-tab[aria-checked="true"] {
    color: var(--td-cream);
}

.progress-charts .heading {
    font-family: var(--td-font-mono);
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--td-cream);
}

.td-rotation-footnote {
    margin-top: 28px;
    font-family: var(--td-font-display);
    font-style: italic;
    font-size: 15px;
    color: var(--td-cream-dim);
}

.counter-para {
    color: var(--td-cream-mute);
}

/* --------------------------------------------------------------------------
   Platform tiles (Watch tab): brand tiles instead of stock imagery
   -------------------------------------------------------------------------- */
.td-platform-tile {
    aspect-ratio: 16 / 9;
    border-radius: 10px;
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    padding: 26px 30px;
    background:
        radial-gradient(ellipse 75% 90% at 80% 15%, rgba(184, 0, 94, 0.28), transparent 58%),
        linear-gradient(150deg, var(--td-violet) 0%, var(--td-violet-deep) 60%, var(--td-charcoal) 100%);
    border: 1px solid var(--td-line);
}

.td-platform-tile i {
    font-size: 42px;
    color: var(--td-cream);
    opacity: 0.92;
}

.td-tile-twitch i { color: var(--td-lilac); }

.tmp-portfolio .portfoli-card-para {
    font-family: var(--td-font-mono);
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 0.06em;
    color: var(--td-lilac);
    text-transform: none;
}

/* --------------------------------------------------------------------------
   Contact form. The site prints no email address anywhere, so this is the
   only door in; it needs to look like the front door and not an afterthought.
   -------------------------------------------------------------------------- */
.td-form {
    background: var(--td-violet-deep);
    border: 1px solid var(--td-line);
    border-radius: 14px;
    padding: 40px;
}

.td-field {
    margin-bottom: 22px;
}

.td-field label {
    display: block;
    margin-bottom: 8px;
    font-family: var(--td-font-mono);
    font-weight: 700;
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--td-lilac);
}

.td-field__hint {
    font-weight: 400;
    letter-spacing: 0.08em;
    color: var(--td-cream-dim);
}

.td-field input,
.td-field textarea {
    width: 100%;
    padding: 13px 16px;
    font-family: var(--td-font-body);
    font-size: 15px;
    color: var(--td-cream);
    background-color: rgba(248, 244, 255, 0.04);
    border: 1px solid var(--td-cream-faint);
    border-radius: 10px;
    transition: border-color 0.2s ease, background-color 0.2s ease;
}

.td-field textarea {
    resize: vertical;
    min-height: 130px;
}

.td-field input::placeholder,
.td-field textarea::placeholder {
    color: var(--td-cream-dim);
}

.td-field input:focus,
.td-field textarea:focus {
    outline: none;
    border-color: var(--td-lilac);
    background-color: rgba(248, 244, 255, 0.07);
}

.td-field input:user-invalid,
.td-field textarea:user-invalid {
    border-color: var(--td-magenta);
}

/* Honeypot: out of sight and out of the tab order, but a real field in the
   DOM, which is the whole point. Not display:none, which bots skip. */
.td-hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.td-turnstile {
    margin-bottom: 22px;
}

.td-form__status {
    margin: 18px 0 0;
    font-size: 14px;
    line-height: 1.5;
    min-height: 1.5em;
    color: var(--td-cream-mute);
}

.td-form__status.is-ok {
    color: var(--td-lilac);
    font-weight: 600;
}

.td-form__status.is-error {
    color: #FF7BA8;
}

.td-form__note {
    margin: 14px 0 0;
    font-size: 12px;
    line-height: 1.6;
    color: var(--td-cream-dim);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.td-footer-wordmark a {
    font-size: 34px;
}

.td-footer-tagline {
    margin-top: 14px;
    font-family: var(--td-font-display);
    font-style: italic;
    font-size: 16px;
    color: var(--td-cream-dim);
    letter-spacing: 0.04em;
}

.td-footer-tagline em {
    font-style: italic;
}

.tmp-footer-area .description {
    color: var(--td-cream-dim);
}

/* ==========================================================================
   Light mode — brand treatment 3: Violet + Magenta on Cream.
   Rides the template's own .tmp-white-version switch.
   ========================================================================== */
body.tmp-white-version {
    --color-heading: var(--td-violet);
    --color-body: #5c4a70;
    --color-card: #ffffff;
    --color-secondary: var(--td-cream);
    --background-color-2: var(--td-cream);
    --background-color-3: #f1eafc;
    --background-color-4: #ece2fa;
    --color-border-white: rgba(40, 8, 62, 0.14);
    --td-line: rgba(40, 8, 62, 0.1);
    --td-cream-mute: #5c4a70;
    --td-cream-dim: #8a7a9c;
    --td-cream-faint: rgba(40, 8, 62, 0.16);
    background: var(--td-cream);
}

body.tmp-white-version .td-banner-wordmark,
body.tmp-white-version .td-card-wordmark,
body.tmp-white-version .td-footer-wordmark a {
    color: var(--td-cream);            /* banner stays violet-dark in light mode */
}

body.tmp-white-version .td-card-wordmark {
    color: var(--td-violet);
}

body.tmp-white-version .td-footer-wordmark a {
    color: var(--td-violet);
}

body.tmp-white-version .custom-title {
    color: #8b40c9;                    /* lilac deepened for contrast on cream */
}

body.tmp-white-version .progress-charts .heading {
    color: var(--td-violet);
}

body.tmp-white-version .td-form {
    background: #ffffff;
    border-color: rgba(40, 8, 62, 0.1);
}

body.tmp-white-version .td-field input,
body.tmp-white-version .td-field textarea {
    color: var(--td-violet);
    background-color: rgba(40, 8, 62, 0.03);
    border-color: rgba(40, 8, 62, 0.15);
}

body.tmp-white-version .td-field input:focus,
body.tmp-white-version .td-field textarea:focus {
    border-color: #7b3fb5;
    background-color: rgba(40, 8, 62, 0.05);
}

body.tmp-white-version .td-field label {
    color: #7b3fb5;
}

body.tmp-white-version .td-form__status {
    color: rgba(40, 8, 62, 0.7);
}

body.tmp-white-version .td-form__status.is-ok {
    color: #6d2a9e;
}

body.tmp-white-version .td-form__status.is-error {
    color: #B8005E;
}

body.tmp-white-version .td-form__note,
body.tmp-white-version .td-field__hint {
    color: rgba(40, 8, 62, 0.45);
}

body.tmp-white-version .td-theme-tabs {
    background: rgba(40, 8, 62, 0.05);
    border-color: rgba(40, 8, 62, 0.18);
}

body.tmp-white-version .td-theme-tab {
    color: rgba(40, 8, 62, 0.45);
}

body.tmp-white-version .td-theme-tab:hover {
    color: var(--td-violet);
}

body.tmp-white-version .td-theme-tab[aria-checked="true"] {
    color: var(--td-cream);
}

/* --------------------------------------------------------------------------
   Restraint pass: magenta is ONE voice per surface.
   Icon chips go violet with lilac icons; the CTA keeps the heat.
   -------------------------------------------------------------------------- */
.about-us-card .card-head .logo-img {
    background: linear-gradient(150deg, var(--td-violet) 0%, var(--td-violet-deep) 100%) !important;
    border: 1px solid var(--td-cream-faint);
}

.about-us-card .card-head .logo-img i {
    color: var(--td-lilac) !important;
}

/* Rotation bars: lilac by default; only the favourite raises its voice */
.progress-charts .progress-bar {
    background: var(--td-lilac);
}

.td-bar-favourite .progress-bar {
    background: var(--td-magenta);
}

/* Platform cards: the template reveals text on hover only; these are doors,
   so the label stays visible (and reachable on touch) */
.tmp-portfolio .portfolio-card-content-wrap {
    opacity: 1;
    pointer-events: inherit;
    bottom: 18px;
    background: rgba(17, 3, 25, 0.72);
    border: 1px solid var(--td-line);
    border-radius: 10px;
    padding: 10px 16px;
    backdrop-filter: blur(4px);
}

.tmp-portfolio .portfolio-card-title {
    font-size: 18px;
    margin-bottom: 0;
}

.tmp-portfolio .portfoli-card-para {
    margin-bottom: 2px;
}

body.tmp-white-version .tmp-portfolio .portfolio-card-content-wrap {
    background: rgba(248, 244, 255, 0.85);
}

/* Social marks keep their own brand colours so they are recognised at a
   glance. Deliberate exception to the palette discipline: these are other
   people's marks, not our decoration. Each network sets its own tokens;
   one rule spends them, so adding a network means adding one line.
   TikTok and Threads are black-brand, so on our dark surface their glyph
   stays cream (that IS their own dark-mode treatment). */
.td-social--twitch    { --td-net: #A970FF; --td-net-solid: #9146FF; --td-net-on: #fff;     --td-net-tint: rgba(145, 70, 255, 0.16);  --td-net-bright: #A970FF; }
.td-social--youtube   { --td-net: #FF4E45; --td-net-solid: #FF0000; --td-net-on: #fff;     --td-net-tint: rgba(255, 0, 0, 0.16);  --td-net-bright: #FF4E45; }
.td-social--instagram { --td-net: #F35C8E; --td-net-solid: #D6249F; --td-net-on: #fff;     --td-net-tint: rgba(225, 48, 108, 0.16);  --td-net-bright: #F35C8E; }
.td-social--tiktok    { --td-net: #F8F4FF; --td-net-solid: #25F4EE; --td-net-on: #010101;  --td-net-tint: rgba(37, 244, 238, 0.14);  --td-net-bright: #25F4EE; }
.td-social--threads   { --td-net: #F8F4FF; --td-net-solid: #F8F4FF; --td-net-on: #110319;  --td-net-tint: rgba(248, 244, 255, 0.10);  --td-net-bright: #F8F4FF; }
.td-social--facebook  { --td-net: #4E92F7; --td-net-solid: #1877F2; --td-net-on: #fff;     --td-net-tint: rgba(24, 119, 242, 0.16); }
.td-social--patreon   { --td-net: #FF6B73; --td-net-solid: #FF424D; --td-net-on: #fff;     --td-net-tint: rgba(255, 66, 77, 0.16);  --td-net-bright: #FF6B73; }

.social-link a.td-social,
.td-contact-socials a.td-social {
    color: var(--td-net) !important;
    background-color: var(--td-net-tint) !important;
    transition: background-color 0.2s ease, color 0.2s ease;
}

/* --------------------------------------------------------------------------
   Platform previews (About pane): portrait 9:16 tiles, one per platform,
   shaped like a phone screen because that is where the content lives. Each
   borrows its platform's --td-net colour for the mark and the edge glow;
   only the Twitch tile (home) is allowed the magenta CTA.
   -------------------------------------------------------------------------- */
.td-preview {
    display: block;
    text-decoration: none;
}

.td-preview__screen {
    position: relative;
    display: flex;
    flex-direction: column;
    aspect-ratio: 9 / 16;
    padding: 18px 16px;
    border-radius: 18px;
    border: 1px solid var(--td-cream-faint);
    background:
        radial-gradient(120% 60% at 50% 0%, var(--td-net-tint) 0%, transparent 60%),
        linear-gradient(170deg, var(--td-violet) 0%, var(--td-violet-darker) 100%);
    overflow: hidden;
    transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.td-preview:hover .td-preview__screen,
.td-preview:focus-visible .td-preview__screen {
    transform: translateY(-4px);
    border-color: var(--td-net);
    box-shadow: 0 18px 40px -22px var(--td-net-tint);
}

.td-preview__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 10px;
    font-size: 16px;
    color: var(--td-net);
    background-color: var(--td-net-tint);
}

.td-preview__chip {
    position: absolute;
    top: 20px;
    right: 16px;
    font-family: var(--td-font-mono);
    font-weight: 700;
    font-size: 9px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--td-cream);
    background-color: var(--td-magenta);
    border-radius: 999px;
    padding: 5px 9px;
}

.td-preview__body {
    display: block;
    margin-top: auto;
}

.td-preview__kind {
    display: block;
    font-family: var(--td-font-mono);
    font-weight: 700;
    font-size: 10px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--td-lilac);
    margin-bottom: 6px;
}

.td-preview__title {
    display: block;
    font-family: var(--td-font-display);
    font-size: 24px;
    line-height: 1.1;
    color: var(--td-cream);
    margin-bottom: 8px;
}

.td-preview__para {
    display: block;
    font-size: 13px;
    line-height: 1.5;
    color: var(--td-cream-mute);
}

.td-preview__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--td-line);
}

.td-preview__handle {
    font-family: var(--td-font-mono);
    font-size: 10px;
    letter-spacing: 0.04em;
    color: var(--td-cream-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.td-preview__go {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    font-size: 11px;
    color: var(--td-cream);
    background-color: rgba(248, 244, 255, 0.10);
    transition: background-color 0.25s ease, color 0.25s ease;
}

.td-preview--home .td-preview__go {
    background-color: var(--td-magenta);
}

.td-preview:hover .td-preview__go {
    background-color: var(--td-net-solid);
    color: var(--td-net-on);
}

/* Phones: two tiles a row would squeeze the copy, so let them breathe. */
@media (max-width: 575px) {
    .td-preview__screen {
        aspect-ratio: auto;
        min-height: 260px;
    }

    .td-preview__title {
        font-size: 20px;
    }
}

body.tmp-white-version .td-preview__screen {
    border-color: rgba(40, 8, 62, 0.12);
    background:
        radial-gradient(120% 60% at 50% 0%, var(--td-net-tint) 0%, transparent 60%),
        linear-gradient(170deg, #ffffff 0%, #f4eefb 100%);
}

body.tmp-white-version .td-preview__title {
    color: var(--td-violet);
}

body.tmp-white-version .td-preview__para {
    color: rgba(40, 8, 62, 0.7);
}

body.tmp-white-version .td-preview__kind {
    color: #7b3fb5;
}

body.tmp-white-version .td-preview__handle {
    color: rgba(40, 8, 62, 0.45);
}

body.tmp-white-version .td-preview__go {
    color: var(--td-violet);
    background-color: rgba(40, 8, 62, 0.08);
}

body.tmp-white-version .td-preview--home .td-preview__go {
    color: var(--td-cream);
    background-color: var(--td-magenta);
}

/* Accordion pills: icon only at rest, expanding to name the platform on
   hover or keyboard focus. width:auto + a max-width cap means each pill
   grows to exactly its own label, and the row reflows around it. */
.td-social-accordion {
    gap: 6px;
}

.td-social-accordion a.td-social {
    width: auto;
    min-width: 40px;
    max-width: 40px;
    padding: 0 12px;
    gap: 0;
    border-radius: 999px;
    justify-content: flex-start;
    overflow: hidden;
    transition: max-width 0.4s cubic-bezier(0.32, 1.15, 0.4, 1),
                gap 0.4s cubic-bezier(0.32, 1.15, 0.4, 1),
                background-color 0.2s ease, color 0.2s ease;
}

.td-social-accordion a.td-social .td-social__name {
    font-family: var(--td-font-mono);
    font-weight: 700;
    font-size: 10px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    opacity: 0;
    transition: opacity 0.22s ease;
}

.td-social-accordion a.td-social:hover,
.td-social-accordion a.td-social:focus-visible {
    max-width: 200px;
    gap: 8px;
}

/* Opened, the pill puts on brand clothes (Duchess, 2026-08-22): a violet
   ground with cream lettering, while the mark itself keeps its platform
   colour. `--td-net-bright` is used rather than `--td-net` on purpose — light
   mode darkens some marks to near-black for legibility on cream, and those
   would disappear against violet. The bright variants are never overridden,
   so the opened pill reads the same in both themes. */
/* The selector carries `.social-link` as well, which puts it one class above
   the platform-solid hover further down this file. Without that, the later
   rule (equal specificity, also !important) would win and repaint the pill in
   the platform's own colour. */
.social-link.td-social-accordion a.td-social:hover,
.social-link.td-social-accordion a.td-social:focus-visible {
    background-color: var(--td-violet) !important;
    background-image: none !important;
    color: var(--td-net-bright) !important;
    /* Violet on the card's near-black sits close in tone, so a lilac hairline
       gives the opened pill an edge. Decorative lilac, which is what lilac is
       for. */
    box-shadow: inset 0 0 0 1px rgba(199, 125, 255, 0.38);
}

.social-link.td-social-accordion a.td-social:hover .td-social__name,
.social-link.td-social-accordion a.td-social:focus-visible .td-social__name {
    color: var(--td-cream) !important;
}

.td-social-accordion a.td-social:hover .td-social__name,
.td-social-accordion a.td-social:focus-visible .td-social__name {
    opacity: 1;
}

/* Touch devices never hover, and seven expanded pills would wrap into a
   three-row block on a phone: stay icons-only there. The marks are
   recognisable and every link keeps its aria-label. */
@media (prefers-reduced-motion: reduce) {
    .td-social-accordion a.td-social {
        transition: background-color 0.2s ease, color 0.2s ease;
    }
}

/* The template slides a magenta disc in on hover; the brand colour is the
   hover state here instead. */
.social-link a.td-social::after,
.td-contact-socials a.td-social::after {
    display: none;
}

.social-link a.td-social:hover,
.td-contact-socials a.td-social:hover {
    color: var(--td-net-on) !important;
    background-color: var(--td-net-solid) !important;
}

/* Instagram's mark is a gradient, not a flat colour. */
.social-link a.td-social--instagram:hover,
.td-contact-socials a.td-social--instagram:hover {
    background-image: radial-gradient(circle at 30% 107%, #FDF497 0%, #FD5949 45%, #D6249F 60%, #285AEB 90%);
}

/* Light mode: pale-brand glyphs go to their true colour so they stay
   legible on cream, and the black-brand marks go properly black. */
body.tmp-white-version .td-social--twitch    { --td-net: #9146FF; }
body.tmp-white-version .td-social--youtube   { --td-net: #E60000; }
body.tmp-white-version .td-social--instagram { --td-net: #D6249F; }
body.tmp-white-version .td-social--facebook  { --td-net: #1877F2; }
body.tmp-white-version .td-social--patreon   { --td-net: #E8323C; }
body.tmp-white-version .td-social--tiktok    { --td-net: #121212; --td-net-tint: rgba(37, 244, 238, 0.22); }
body.tmp-white-version .td-social--threads   { --td-net: #121212; --td-net-tint: rgba(40, 8, 62, 0.08); }

/* Tablet and mobile: keep the template's tight banner so the profile card
   sits high (its photo is the hero on a phone, not the gradient). The
   wordmark scales down to fit the visible band above the card, and the
   schedule line drops on phones because the card repeats it anyway. */
@media (max-width: 1199px) {
    .tmp-breadcrumb-image {
        height: 400px;
    }

    .td-banner-inner {
        justify-content: flex-start;
        padding-top: 52px;
    }

    .td-banner-eyebrow {
        font-size: 11px;
        letter-spacing: 0.24em;
        margin-bottom: 12px;
    }
}

@media (max-width: 767px) {
    .tmp-breadcrumb-image {
        height: 300px;
    }

    .td-banner-inner {
        padding-top: 22px;
    }

    .td-banner-eyebrow {
        font-size: 10px;
        letter-spacing: 0.2em;
        margin-bottom: 8px;
    }

    .td-banner-wordmark {
        font-size: 34px;
        margin-bottom: 0;
    }

    .td-banner-frame {
        display: none;
    }

    .td-monogram {
        font-size: 84px;
    }

    .td-form {
        padding: 26px 20px;
    }

    /* Seven marks on one row: a wrapped single chip reads as a mistake. */
    .social-link {
        gap: 6px;
    }

    .social-link a.td-social {
        width: 38px;
        height: 38px;
        min-width: 38px;
    }
}

/* ==========================================================================
   The Estate — Discord community CTA (profile card)
   Deliberately apart from the social row: the socials are handles to follow,
   this is a room to walk into. It wears Discord's own blurple rather than
   magenta, which keeps the brand's single raised voice for the Twitch tile
   and still reads as unmistakably Discord on a phone.
   ========================================================================== */
.td-discord-btn {
    --td-blurple: #5865F2;
    --td-blurple-lift: #6B77F5;
    /* inline-flex, so the pill is only as wide as its content asks for and
       centres in the card rather than stretching the full width
       (Duchess, 2026-08-22). */
    display: inline-flex;
    align-items: center;
    gap: 12px;
    margin-top: 22px;
    padding: 12px 18px;
    /* Pill, to echo the social chips it sits under (Duchess, 2026-08-22). */
    border-radius: 999px;
    background: var(--td-blurple);
    border: 1px solid rgba(255, 255, 255, 0.14);
    box-shadow: 0 10px 26px rgba(88, 101, 242, 0.32);
    color: #fff;
    text-align: left;
    text-decoration: none;
    transition: background-color 0.2s ease, box-shadow 0.25s ease, transform 0.2s ease;
}

.td-discord-btn:hover,
.td-discord-btn:focus-visible {
    background: var(--td-blurple-lift);
    box-shadow: 0 14px 32px rgba(88, 101, 242, 0.46);
    transform: translateY(-2px);
    color: #fff;
}

.td-discord-btn__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 38px;
    height: 38px;
    /* Circular, like the social chips the pill sits under. */
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.16);
    font-size: 19px;
}

.td-discord-btn__copy {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.td-discord-btn__lead {
    font-family: var(--td-font-display);
    font-size: 18px;
    line-height: 1.15;
    white-space: nowrap;
}

.td-discord-btn__sub {
    font-family: var(--td-font-mono);
    font-weight: 600;
    font-size: 10px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.82);
    white-space: nowrap;
}

.td-discord-btn__arrow {
    margin-left: auto;
    font-size: 14px;
    opacity: 0.9;
    transition: transform 0.2s ease;
}

.td-discord-btn:hover .td-discord-btn__arrow {
    transform: translateX(3px);
}

/* Blurple is a fixed platform colour, so it carries into light mode
   unchanged; only the shadow softens against cream. */
body.tmp-white-version .td-discord-btn {
    border-color: rgba(40, 8, 62, 0.12);
    box-shadow: 0 10px 24px rgba(88, 101, 242, 0.26);
}

/* ==========================================================================
   Light mode keeps the card's magenta bloom.
   The template kills the glow outright in light mode
   (`.tmp-white-version.index-8 .tmp-contact-about-inner::after {display:none
   !important}`), which lost a genuinely nice effect (Duchess, 2026-08-22).
   Restoring it needs one class more than the template's selector plus the
   flag, and a gentler magenta so it blooms on cream instead of staining it.
   ========================================================================== */
body.tmp-white-version.index-8 .tmp-contact-about-inner::after {
    display: block !important;
    background: rgba(184, 0, 94, 0.5) !important;
    filter: blur(200px) !important;
}

/* ==========================================================================
   Centred section head (About): the tagline is the moment on this pane, so
   it sits centred on one line with the eyebrow and the intro beneath it.
   ========================================================================== */
/* Carries `.section-head` too, to match the specificity of the template's
   `.section-head.text-align-left` — the markup has both classes, and without
   this the template won and the heading never actually centred. brand.css
   loads last, so equal specificity is enough. */
.section-head.td-section-head--centred {
    text-align: center;
}

.td-section-head--centred .custom-title,
.td-section-head--centred .title {
    justify-content: center;
}

.td-section-head--centred .title {
    text-wrap: balance;
}

/* The centred moment is the heading only. The intro paragraph is body copy:
   full width and left-aligned like the rest of the pane (Duchess, 2026-08-23
   — my centring it with a reading-width cap gave it padding she never asked
   for). It has to be set explicitly, or it inherits the centring above. */
.td-section-head--centred .description {
    text-align: left;
    max-width: none;
    margin-left: 0;
    margin-right: 0;
}

/* The sidebar is only ~219px wide inside its padding, and the pill at full
   size measures 260px — wider than the card itself, so with an auto width it
   stuck out over the edge. On the desktop rail everything steps down a notch
   so the pill fits the column with room to spare; phones keep the full size,
   where the card is wide enough for it. */
@media (min-width: 1400px) {
    .td-discord-btn {
        padding: 9px 14px;
        gap: 10px;
    }

    .td-discord-btn__icon {
        flex: 0 0 34px;
        height: 34px;
        font-size: 17px;
    }

    .td-discord-btn__lead {
        font-size: 15px;
    }

    .td-discord-btn__sub {
        font-size: 9px;
        letter-spacing: 0.06em;
    }

    .td-discord-btn__arrow {
        font-size: 13px;
    }
}

/* --------------------------------------------------------------------------
   PLATFORM PREVIEW CLIPS
   The tile gains a looping clip BEHIND everything it already draws. The
   design does not change: the same gradient still sits between the clip and
   the copy, which is what keeps the text legible over moving video.
   -------------------------------------------------------------------------- */
.td-preview__clip {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    border-radius: inherit;
}

.td-preview__clip video {
    width: 100%;
    height: 100%;
    /* cover, not contain: below 576px the tile abandons its 9:16 ratio for a
       260px auto height, so the clip MUST crop rather than letterbox. */
    object-fit: cover;
    display: block;
}

/* The scrim. Without it the copy sits straight on moving gameplay and becomes
   unreadable for a few frames at a time — the worst kind of unreadable,
   because it looks fine in a screenshot. Heavier at the bottom, where the
   paragraph, handle and arrow live. */
.td-preview__screen--clip::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
    /* The ramp steepens right where the copy begins. Reserving five lines for
       the paragraph pulled the eyebrow up onto the clip's own
       "the_tech_duchess" band, so on the TikTok tile "THE SHORT ONES" and
       that band's text ended up side by side. Sinking the backdrop there
       lets her labels win without dimming the facecam above. */
    background: linear-gradient(
        180deg,
        rgba(26, 21, 37, 0.30) 0%,
        rgba(26, 21, 37, 0.40) 30%,
        rgba(26, 21, 37, 0.80) 46%,
        rgba(26, 21, 37, 0.90) 74%,
        rgba(26, 21, 37, 0.96) 100%
    );
}

/* Everything the tile already drew has to sit above the clip and the scrim.
   These three are statically positioned, so they need a position before
   z-index means anything. */
.td-preview__screen--clip > .td-preview__mark,
.td-preview__screen--clip > .td-preview__body,
.td-preview__screen--clip > .td-preview__foot {
    position: relative;
    z-index: 2;
}

/* The chip is ALREADY absolute (top right of the tile) and must stay that
   way — z-index alone is enough. Giving it position: relative turned it into
   a full-width magenta bar across the tile, which is exactly what happened
   the first time this was written. */
.td-preview__screen--clip > .td-preview__chip {
    z-index: 2;
}

/* LIGHT MODE INVERTS THE SCRIM, and it has to.
   The light tile is cream (#fff -> #f4eefb) with DARK violet copy, so a dark
   scrim makes the text unreadable rather than readable — dark on dark, which
   is worse than no scrim at all. Verified by rendering it the wrong way
   round first: the paragraphs vanished completely. */
body.tmp-white-version .td-preview__screen--clip::before {
    background: linear-gradient(
        180deg,
        rgba(255, 255, 255, 0.38) 0%,
        rgba(252, 249, 255, 0.52) 30%,
        rgba(250, 246, 255, 0.88) 46%,
        rgba(248, 244, 255, 0.94) 74%,
        rgba(244, 238, 251, 0.98) 100%
    );
}

/* Someone who has asked their OS for less motion gets a still tile. There is
   deliberately no CSS rule for it: a <video> that is never played already
   renders its own poster attribute, so main.js checking the same media query
   before it calls play() is the entire implementation. Hiding the video and
   restoring the still with a background-image would mean duplicating the
   poster URL into an inline style, and showing nothing at all the day that
   was forgotten. */

/* --------------------------------------------------------------------------
   "WHERE TO WATCH" HEADING ROW
   The live nights sit here, level with the heading, rather than on a tile.
   On one platform they read as a preference (Duchess, 2026-08-23); belonging
   to the section, they read as her schedule.
   -------------------------------------------------------------------------- */
.td-watch-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px 24px;
    flex-wrap: wrap;
    margin-bottom: 30px;
}

.td-watch-nights {
    margin: 0;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 16px;
    border-radius: 999px;
    border: 1px solid var(--td-cream-faint);
    background-color: rgba(199, 125, 255, 0.10);
    font-family: var(--td-font-mono);
    font-size: 12px;
    letter-spacing: 0.06em;
    color: var(--td-cream-soft);
    white-space: nowrap;
}

/* "Live" is the label, the nights are the content. Lilac is decorative-only
   by the brand rules, which is exactly what a label is. */
.td-watch-nights span {
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--td-lilac);
}

body.tmp-white-version .td-watch-nights {
    border-color: rgba(40, 8, 62, 0.14);
    background-color: rgba(40, 8, 62, 0.05);
    color: var(--td-violet);
}

body.tmp-white-version .td-watch-nights span {
    color: var(--td-magenta);
}

/* Phones: the heading and the nights stack, and the pill goes left with the
   heading rather than stranded on the right. */
@media (max-width: 575px) {
    .td-watch-head {
        justify-content: flex-start;
        gap: 12px;
    }
}

/* --------------------------------------------------------------------------
   PREVIEW TILES: EYEBROW AND PLATFORM NAME ON A SET LINE
   Duchess, 2026-08-23: "Live", "The Keepers" and "The Short Ones" should sit
   at the same height across the three tiles, and the platform names with
   them, with the paragraph simply flowing underneath.

   THE CAUSE was bottom-alignment. `.td-preview__body` uses margin-top: auto,
   so each block is pinned to the tile floor and its TOP is wherever the
   paragraph's line count leaves it. Measured across nine widths: the three
   tiles already agreed everywhere the paragraphs happened to wrap to the
   same number of lines, and only disagreed where they did not — 5/5/4 at
   1440px and 4/5/4 at 768px, a 20px step each time, exactly one line.

   THE FIX is to reserve a fixed number of lines for the paragraph, so every
   body is the same height and bottom-alignment then puts every eyebrow and
   every title on the same line. Five lines, because five is the worst case
   measured anywhere the 9:16 ratio is enforced.

   This costs nothing: the float is ABOVE the body, over the clip, so a short
   paragraph moves UP into backdrop rather than pushing anything down. The
   16px above the foot is fixed margin and is not touched.

   Scoped to 576px and up on purpose. Below that the tile drops its ratio for
   an auto height, so it grows to fit its own content and the eyebrows already
   align — measured at 575, 414 and 390. Reserving lines there would only add
   empty space to a phone.
   -------------------------------------------------------------------------- */
@media (min-width: 576px) {
    .td-preview__para {
        /* 13px * 1.5 = 19.5px a line, so five lines. Kept as a calc off the
           real font-size and line-height rather than a magic 100px, so
           changing either does not silently break the alignment. */
        min-height: calc(5 * 13px * 1.5);
    }
}

/* The eyebrow must never wrap: two lines of "THE SHORT ONES" would push that
   one title down on its own and undo all of the above. It is short mono text,
   so nowrap costs nothing. */
.td-preview__kind {
    white-space: nowrap;
}
