/* ============================================================
   D.ROD brand primitives — the mark, the wordmark, the spinner.
   Brand kit v1.0 (Jul 2026) + Motion Kit v1.0 (Aug 2026).

   "The dot between the D and the R is the sun."
   One sun, one waterline. Every animation here is the sun or the
   water doing something. Nothing slides, bounces, or shimmers.

   Pure CSS: no SVG, no JS, no build step. Load AFTER theme.css.
   ============================================================ */

/* ---------- keyframes ----------
   The Motion Kit explicitly supersedes sheet 10 of the brand book:
   the rays rotate, the sun holds still. A spinning sun looks like a fan. */
@keyframes raySpin    { to { transform: rotate(360deg); } }
@keyframes rayBreathe { 0%, 100% { transform: scale(.8); opacity: .45; } 50% { transform: scale(1.12); opacity: 1; } }
@keyframes rayBurst   { 0% { transform: scale(.45); opacity: 0; } 30% { transform: scale(1.18); opacity: 1; } 62%, 100% { transform: scale(1.62); opacity: 0; } }
@keyframes dotSettle  { 0% { transform: translateY(-140%); opacity: 0; } 60%, 100% { transform: translateY(0); opacity: 1; } }
@keyframes drodGlint  { 0% { transform: translateX(-140%); } 100% { transform: translateX(360%); } }
@keyframes drodRipple { 0% { transform: scale(.35); opacity: .75; } 100% { transform: scale(2.3); opacity: 0; } }

/* ============================================================
   THE MARK
   Ring + rays + sun + waterline. Size is driven by width/height.
   Set --mark-ink to --deep-water (on light) or --paper (reversed).
   ============================================================ */
.drod-mark {
    --mark-ink: var(--deep-water, #1d2d3d);
    --mark-water: var(--signal, #1b9dd8);
    --mark-stroke: 1.5px;
    box-sizing: border-box;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: var(--mark-stroke) solid var(--mark-ink);
    position: relative;
    overflow: hidden;
    flex: none;
    display: block;
}

/* Rays: 8 at 7deg on a 45deg period, offset -3.5deg so each is centred on the axis. */
.drod-mark::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 30%;
    transform: translate(-50%, -50%);
    width: 46%;
    height: 46%;
    border-radius: 50%;
    background: repeating-conic-gradient(from -3.5deg, var(--mark-ink) 0deg 7deg, transparent 7deg 45deg);
}

/* Sun disc — sits fully above the waterline (spans 19%-41%, water tops at 66%). */
.drod-mark::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 30%;
    transform: translate(-50%, -50%);
    width: 22%;
    height: 22%;
    border-radius: 50%;
    background: var(--mark-ink);
}

/* The waterline is the one child element — everything else is a pseudo. */
.drod-mark > .drod-water {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 34%;
    background: var(--mark-water);
    display: block;
}

/* Reversed, on Deep Water. The water STAYS Signal — that is the point. */
.drod-mark--reversed { --mark-ink: var(--paper, #f2f2f3); }

/* ---------- the size ladder ----------
   Under 32px the rays drop. Under 24px the sun drops too. Under 20px the
   ring closes into a solid disc so the horizon still reads: that solid
   form is the favicon and the app badge. */
.drod-mark--sm::before { content: none; }                       /* < 32px: no rays */
.drod-mark--xs::before,
.drod-mark--xs::after  { content: none; }                       /* < 24px: no rays, no sun */
.drod-mark--solid {                                             /* < 20px: closed disc */
    border: 0;
    background: var(--mark-ink);
}
.drod-mark--solid::before,
.drod-mark--solid::after { content: none; }
.drod-mark--solid > .drod-water { height: 38%; }

/* Stroke scales with diameter: >=88px 2-2.5px, 18-56px 1.5px, <=12px 1px. */
.drod-mark--lg   { --mark-stroke: 2px;   width: 96px;  height: 96px; }
.drod-mark--xl   { --mark-stroke: 2.5px; width: 112px; height: 112px; }
.drod-mark--tiny { --mark-stroke: 1px; }

/* ---------- the tile ----------
   The app-icon lockup: reversed mark on a Deep Water tile at 64%. This is the
   32px favicon spec exactly (ring + water, no sun, no rays), so a 32px nav slot
   and the browser tab show the same object. Square by default; UI chrome may
   round it, but the exported app icon never is (iOS adds its own corner). */
.drod-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: var(--deep-water, #1d2d3d);
    flex: none;
}
.drod-tile > .drod-mark { width: 64%; height: 64%; }

/* ---------- the avatar ----------
   D.ROD's face in the chat. THE AVATAR CIRCLE IS THE MARK: the water fills the
   bottom of this circle directly and the sun sits above it, so there is exactly
   one circle on screen. The earlier version nested a ringed mark inside a round
   tile inside a bordered <img>, which read as three concentric rings at 34px and
   lost the horizon completely.

   Light ground on purpose: the book puts circular crops on Mist because a dark
   disc disappears against a dark thread.

   Thinking state: the rays SHOOT OUTWARD from the sun and fade. They do not
   rotate. Two layers on a staggered loop so the emission is continuous rather
   than a visible restart, over a steady base ray set that never moves. This is
   the book's own "the logo thinks", and it is why nothing spins beside it. */
.drod-avatar {
    --av-ink: var(--deep-water, #1d2d3d);
    --av-ground: var(--mist, #eef6ff);
    --av-sun-y: 34%;
    box-sizing: border-box;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--av-ground);
    position: relative;
    overflow: hidden;
    flex: none;
    display: block;
}

/* Base rays: always lit, never moving. Bigger than the standalone mark's,
   because with no ring the whole circle is available. */
.drod-avatar::before {
    content: "";
    position: absolute;
    left: 50%;
    top: var(--av-sun-y);
    width: 58%;
    height: 58%;
    margin: -29% 0 0 -29%;
    border-radius: 50%;
    background: repeating-conic-gradient(from -3.5deg, var(--av-ink) 0deg 7deg, transparent 7deg 45deg);
    opacity: .55;
}

/* The sun. Sits above the waterline and never moves. */
.drod-avatar::after {
    content: "";
    position: absolute;
    left: 50%;
    top: var(--av-sun-y);
    width: 26%;
    height: 26%;
    margin: -13% 0 0 -13%;
    border-radius: 50%;
    background: var(--av-ink);
    z-index: 2;
}

/* The waterline, clipped by the avatar circle itself. */
.drod-avatar > .drod-water {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 32%;
    background: var(--signal, #1b9dd8);
    display: block;
    z-index: 1;
}

/* The emitted rays. Idle at rest; only the thinking state runs them. Centred
   with negative margins rather than a translate so `scale` has the transform to
   itself and the emission stays perfectly concentric. */
.drod-avatar > .drod-rays,
.drod-avatar > .drod-rays::after {
    content: "";
    position: absolute;
    left: 50%;
    top: var(--av-sun-y);
    width: 58%;
    height: 58%;
    margin: -29% 0 0 -29%;
    border-radius: 50%;
    background: repeating-conic-gradient(from -3.5deg, var(--av-ink) 0deg 7deg, transparent 7deg 45deg);
    opacity: 0;
    display: block;
}

@keyframes rayEmit {
    0%   { transform: scale(.42); opacity: 0; }
    18%  { opacity: .85; }
    100% { transform: scale(1.55); opacity: 0; }
}

.drod-avatar--thinking > .drod-rays,
.drod-avatar--thinking > .drod-rays::after {
    animation: rayEmit 1.9s cubic-bezier(.22, .7, .2, 1) infinite;
}
/* Half-phase offset, so one wave is always mid-flight. */
.drod-avatar--thinking > .drod-rays::after { animation-delay: .95s; }

/* Thinking also lifts the sun a touch and warms the base rays, so the avatar
   reads as awake rather than merely animated. */
.drod-avatar--thinking::before { opacity: .8; }

/* ---------- alive ----------
   The idle state, for the ONE avatar that represents D.ROD itself rather than a
   message: the header. Its base rays turn at the Sunrise cadence, 14s a turn,
   and the sun holds still -- the same motion and the same speed as the spinner,
   because it is the same object. At 14s it is barely perceptible frame to
   frame, which is the point: the mark is alive, not busy. The book's "1s reads
   as anxious" applies here more than anywhere, since this one never stops.

   Deliberately NOT on .drod-avatar itself. Every message in the thread carries
   an avatar, so putting this on the base class would leave dozens of elements
   animating forever, which is both a battery cost and the fidget the Motion Kit
   exists to prevent. Thinking-state ray emission layers on top of this
   untouched: it runs on .drod-rays, a different element. */
.drod-avatar--alive::before { animation: raySpin 14s linear infinite; }

@media (prefers-reduced-motion: reduce) {
    /* Stop turning, stay lit -- same bargain the spinner makes. */
    .drod-avatar--alive::before { animation: none !important; opacity: .72; }
}

/* Reversed, for a light surface. */
.drod-avatar--reversed {
    --av-ground: var(--deep-water, #1d2d3d);
    --av-ink: var(--paper, #f2f2f3);
}

.drod-avatar--lg { width: 44px; height: 44px; }
.drod-avatar--xl { width: 64px; height: 64px; }

@media (prefers-reduced-motion: reduce) {
    .drod-avatar--thinking > .drod-rays,
    .drod-avatar--thinking > .drod-rays::after {
        animation: none !important;
        opacity: .38;
        transform: scale(1.15);
    }
}

/* ============================================================
   THE WORDMARK
   D + a true disc + ROD. The disc is optically sized to the stroke
   weight of the R; a period would read as an accident at display size.
   ============================================================ */
.drod-wordmark {
    font-family: var(--font-display, 'Barlow Condensed', sans-serif);
    font-weight: 600;
    line-height: .85;
    letter-spacing: -.02em;
    display: inline-flex;
    align-items: baseline;
    /* The book says 2px, but at ITS display size (52px). Hardcoded px does not
       shrink with the type, so an 18px header rendered "D. ROD" with what reads
       as a word space. em holds the ratio at every size. */
    gap: 0.04em;
    color: inherit;
    white-space: nowrap;
}
.drod-wordmark > .drod-dot {
    display: inline-block;
    width: .2em;
    height: .2em;
    border-radius: 50%;
    background: currentColor;
    flex: none;
    margin: 0;
    animation: none;
}

/* Under 20px the disc becomes the typeface's own period and the MARK
   carries the sun instead. Nav, email, favicon lockups. */
.drod-wordmark--sm {
    gap: 0.02em;
    letter-spacing: -.01em;
}
.drod-wordmark--sm > .drod-dot {
    width: auto;
    height: auto;
    border-radius: 0;
    background: none;
}
.drod-wordmark--sm > .drod-dot::before { content: "."; }

/* On Deep Water the dot alone takes Signal — the only place it takes colour,
   and the reason the reversed lockup is the one to use on dark UI: the sun
   is visibly on. */
.drod-wordmark--reversed > .drod-dot { background: var(--signal, #1b9dd8); }

/* The dot drops into place once per session. The sun coming up.
   Letters never animate. */
.drod-wordmark--settle > .drod-dot { animation: dotSettle 420ms cubic-bezier(.22, .7, .2, 1) 1; }

/* ============================================================
   THE SPINNER — "Sunrise"
   Eight Signal rays turn around a sun that never moves. 14s a turn
   reads as warm; 1s reads as anxious. Ray count drops with the size,
   never the speed.
   ============================================================ */
.drod-spinner {
    --mark-ink: var(--deep-water, #1d2d3d);
    --spin-rays: repeating-conic-gradient(from -3.5deg, var(--signal, #1b9dd8) 0deg 7deg, transparent 7deg 45deg);
    box-sizing: border-box;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: 1.5px solid var(--mark-ink);
    position: relative;
    overflow: hidden;
    flex: none;
    display: block;
}
.drod-spinner > .drod-rays {
    position: absolute;
    left: 50%;
    top: 30%;
    width: 64%;
    height: 64%;
    margin: -32% 0 0 -32%;
    display: block;
    animation: raySpin 14s linear infinite;
}
.drod-spinner > .drod-rays::before {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: var(--spin-rays);
    animation: rayBreathe 2.4s ease-in-out infinite;
}
.drod-spinner > .drod-sun {
    position: absolute;
    left: 50%;
    top: 30%;
    transform: translate(-50%, -50%);
    width: 22%;
    height: 22%;
    border-radius: 50%;
    background: var(--mark-ink);
    display: block;
}
.drod-spinner > .drod-water {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 34%;
    background: var(--signal, #1b9dd8);
    display: block;
}
.drod-spinner--reversed { --mark-ink: var(--paper, #f2f2f3); }

/* 96 · full. First answer of a session, empty states, cold start. 8 rays. */
.drod-spinner--full { width: 96px; height: 96px; border-width: 2px; }

/* 24 · inline. Four rays, NO sun disc: the rays are the sun at this size.
   Beside the input, in a row, in a toast. */
.drod-spinner--inline {
    width: 24px;
    height: 24px;
    --spin-rays: repeating-conic-gradient(from -3.5deg, var(--signal, #1b9dd8) 0deg 14deg, transparent 14deg 90deg);
}
.drod-spinner--inline > .drod-rays { width: 70%; height: 70%; margin: -35% 0 0 -35%; }
.drod-spinner--inline > .drod-sun { display: none; }
.drod-spinner--inline > .drod-water { height: 36%; }

/* Rayburst: on the first token the rays burst out once over 520ms and vanish,
   the sunrise finishing. They never return mid-answer. */
.drod-spinner--burst > .drod-rays { animation: none; }
.drod-spinner--burst > .drod-rays::before {
    animation: rayBurst 520ms cubic-bezier(.2, .8, .2, 1) 1 forwards;
}

/* Skeleton lines take one glint travelling left to right, the light on the
   water, same rhythm as the rays. Nothing shimmers on the wordmark itself. */
.drod-glint {
    position: relative;
    overflow: hidden;
}
.drod-glint::after {
    content: "";
    position: absolute;
    inset: 0;
    width: 34%;
    background: linear-gradient(90deg, transparent, var(--signal-light, #6fc9e8), transparent);
    opacity: .6;
    animation: drodGlint 2.2s ease-in-out infinite;
}

/* A stone in the water, the only acknowledgement a submit gets. */
.drod-ripple::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 100%;
    height: 100%;
    margin: -50% 0 0 -50%;
    border-radius: 50%;
    border: 1.5px solid var(--signal, #1b9dd8);
    animation: drodRipple 700ms ease-out 1;
    pointer-events: none;
}

/* ============================================================
   REDUCED MOTION
   The rays stop turning and simply stand out at 72%, a lit sun instead
   of a spinning one. Nothing else animates at all, and no state becomes
   unreadable.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    .drod-spinner > .drod-rays,
    .drod-spinner--burst > .drod-rays::before,
    .drod-wordmark--settle > .drod-dot,
    .drod-ripple::after {
        animation: none !important;
    }
    .drod-spinner > .drod-rays::before {
        animation: none !important;
        opacity: .72;
        transform: none;
    }
    .drod-glint::after { display: none; }
}
