/* ── Thinkery — geometric art (v8) ─────────────────────────────
   Square-based SVG compositions: one large piece per hero, one
   small piece per key section, tiny glyphs on the product
   sheets. Hairline strokes, monochrome plus the sage accent.
   All motion is opacity/transform only.

   Triggering: hero pieces (.art--live) run on their own; section
   pieces wait for the shared reveal to add .is-in to their
   wrapper. Reduced motion and no-JS get a meaningful end state. */

.art {
    display: block;
    width: 100%;
    height: auto;
}

.art rect, .art line, .art path { vector-effect: non-scaling-stroke; }

.art rect, .art line {
    transform-box: fill-box;
    transform-origin: center;
}

/* ── shared keyframes ────────────────────────────────────────── */
@keyframes a-blink {
    0%, 100% { opacity: 0; }
    4%       { opacity: 0.55; }
    9%       { opacity: 0; }
}

@keyframes a-keep {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: var(--o, 0.9); transform: translateY(0); }
}

@keyframes a-pop {
    from { opacity: 0; transform: scale(0.6); }
    to   { opacity: 1; transform: none; }
}

@keyframes a-rise {
    0%   { opacity: 0; transform: translateY(0); }
    10%  { opacity: 0.85; }
    82%  { opacity: 0.85; }
    96%  { opacity: 0; transform: translateY(var(--ty, -80px)); }
    100% { opacity: 0; transform: translateY(var(--ty, -80px)); }
}

@keyframes a-run {
    0%   { opacity: 0; transform: translateX(0); }
    8%   { opacity: 0.9; }
    84%  { opacity: 0.9; }
    97%  { opacity: 0; transform: translateX(var(--tx, 100px)); }
    100% { opacity: 0; transform: translateX(var(--tx, 100px)); }
}

@keyframes a-fill {
    from { opacity: 0; transform: scaleX(0); }
    to   { opacity: 1; transform: scaleX(1); }
}

@keyframes a-flash {
    0%, 100% { opacity: 0; }
    12%      { opacity: 0.45; }
    26%      { opacity: 0; }
}

@keyframes a-pulse {
    0%, 100% { opacity: 0.55; }
    50%      { opacity: 1; }
}

/* ════ HOME SECTION PIECES (v7.4, reveal-triggered) ═══════════ */

.al-grid, .af-slot, .ay-know, .ay-machine, .as-q,
.af-line, .af-base, .ay-wire {
    stroke: var(--line);
    stroke-width: 1;
}

/* 01 lab: trials flare and die, one survives */
.al-b {
    fill: var(--text-secondary);
    opacity: 0;
    animation: a-blink 9.6s linear var(--d, 0s) infinite paused;
}

.al-keep {
    fill: var(--accent);
    opacity: 0.9;
    animation: al-keep 9.6s linear infinite paused;
}

@keyframes al-keep {
    0%, 46%  { opacity: 0; }
    52%, 96% { opacity: 0.9; }
    100%     { opacity: 0; }
}

/* 02 field: session resets to zero, knowledge stays */
.af-s {
    fill: var(--text-secondary);
    opacity: 0;
    animation: af-session 7.2s linear var(--d, 0s) infinite paused;
}

.af-k {
    fill: var(--accent);
    opacity: 0.85;
    animation: a-keep 1s var(--ease-out) var(--d, 0s) both paused;
    --o: 0.85;
}

@keyframes af-session {
    0%        { opacity: 0; }
    6%, 52%   { opacity: 0.5; }
    56%, 100% { opacity: 0; }
}

/* 03 layer: particles rise from knowledge through the band */
.ay-band {
    fill: var(--accent);
    opacity: 0.85;
    animation: a-pulse 6s ease-in-out infinite paused;
}

.ay-dot {
    fill: var(--text);
    opacity: 0;
    --ty: -78px;
    animation: a-rise 4.2s linear var(--d, 0s) infinite paused;
}

/* 04 stack: four squares click into formation */
.as-frame {
    stroke: var(--line);
    stroke-width: 1;
    stroke-dasharray: 4 5;
}

.as-q { animation: 0.9s var(--ease-out) both paused; }
.as-q--tl { animation-name: as-in-tl; animation-delay: 0.1s; }
.as-q--tr { animation-name: as-in-tr; animation-delay: 0.3s; }
.as-q--bl { animation-name: as-in-bl; animation-delay: 0.5s; }
.as-q--br { animation-name: as-in-br; animation-delay: 0.7s; }

.as-q--building {
    stroke-dasharray: 3 4;
    stroke: var(--text-tertiary);
}

.as-core {
    fill: var(--accent);
    animation: a-pop 1s var(--ease-out) 1.3s both paused;
}

@keyframes as-in-tl { from { opacity: 0; transform: translate(-10px, -10px); } to { opacity: 1; transform: none; } }
@keyframes as-in-tr { from { opacity: 0; transform: translate(10px, -10px); }  to { opacity: 1; transform: none; } }
@keyframes as-in-bl { from { opacity: 0; transform: translate(-10px, 10px); }  to { opacity: 1; transform: none; } }
@keyframes as-in-br { from { opacity: 0; transform: translate(10px, 10px); }   to { opacity: 1; transform: none; } }

/* ════ HERO PIECES (.art--live, self-running) ═════════════════ */

/* hero strokes read slightly stronger — the piece is large */
.art--live { --hairline: rgba(236, 236, 234, 0.24); }

/* home: the experiment field */
.hx-cell { stroke: var(--hairline); stroke-width: 1; }

.hx-b {
    fill: var(--text-secondary);
    opacity: 0;
    animation: a-blink 9.6s linear var(--d, 0s) infinite;
}

.hx-k {
    fill: var(--accent);
    --o: 0.85;
    animation: a-keep 1.1s var(--ease-out) var(--d, 0s) both;
}

/* products: the stack */
.hs-wire { stroke: var(--hairline); stroke-width: 1; }

.hs-q {
    stroke: var(--hairline);
    stroke-width: 1;
    animation: a-pop 0.9s var(--ease-out) var(--d, 0s) both;
}

.hs-q--building {
    stroke-dasharray: 4 5;
    stroke: var(--text-tertiary);
}

.hs-core {
    fill: var(--accent);
    animation: a-pulse 4.8s ease-in-out infinite;
}

.hs-dot {
    fill: var(--text);
    opacity: 0;
    --ty: -350px;
    animation: a-rise 4.8s linear var(--d, 0s) infinite;
}

/* about: experiment to company */
.hb-line, .hb-tick { stroke: var(--hairline); stroke-width: 1; }

.hb-q { stroke: var(--hairline); stroke-width: 1; }

.hb-p {
    fill: var(--accent);
    opacity: 0;
    animation: a-flash 6s linear var(--d, 0s) infinite;
}

.hb-run {
    fill: var(--accent);
    opacity: 0;
    --tx: 428px;
    animation: a-run 6s linear infinite;
}

/* vision: the thinking layer XL */
.hv-frame, .hv-wire { stroke: var(--hairline); stroke-width: 1; }

.hv-band {
    fill: var(--accent);
    opacity: 0.85;
    animation: a-pulse 6s ease-in-out infinite;
}

.hv-dot {
    fill: var(--text);
    opacity: 0;
    --ty: -330px;
    animation: a-rise 5.2s linear var(--d, 0s) infinite;
}

/* advisory: three steps */
.hd-base, .hd-tick { stroke: var(--hairline); stroke-width: 1; }

.hd-q {
    stroke: var(--hairline);
    stroke-width: 1;
    animation: a-pop 0.9s var(--ease-out) var(--d, 0s) both;
}

.hd-slope {
    stroke: var(--accent);
    stroke-width: 1.5;
    transform-origin: left center;
    animation: a-fill 0.9s var(--ease-out) 1.3s both;
}

.hd-m {
    fill: var(--accent);
    animation: a-pop 0.6s var(--ease-out) var(--d, 0s) both;
}

/* journal: the logbook */
.hj-slot { stroke: var(--hairline); stroke-width: 1; }
.hj-tick { stroke: var(--hairline); stroke-width: 1; }

.hj-fill {
    fill: var(--text-secondary);
    opacity: 0.4;
    transform-origin: left center;
    animation: a-fill 0.8s var(--ease-out) var(--d, 0s) both;
}

.hj-fill--new {
    fill: var(--accent);
    opacity: 0.85;
    animation:
        a-fill 0.8s var(--ease-out) var(--d, 0s) both,
        a-pulse 4s ease-in-out 3.2s infinite;
}

/* contact: the signal */
.hc-frame { stroke: var(--hairline); stroke-width: 1; }
.hc-wire { stroke: var(--hairline); stroke-width: 1; }

.hc-core {
    fill: var(--accent);
    opacity: 0;
    animation: a-flash 4.5s linear 3.6s infinite;
}

.hc-dot {
    fill: var(--text);
    opacity: 0;
    --tx: 160px;
    animation: a-run 4.5s linear var(--d, 0s) infinite;
}

.hc-dot--reply {
    fill: var(--accent);
    --tx: -160px;
}

/* ════ SUB-PAGE SECTION PIECES (reveal-triggered) ═════════════ */

/* rules: four decisions, a frame closes around them */
.ru-q { stroke: var(--line); stroke-width: 1; animation: a-keep 0.8s var(--ease-out) var(--d, 0s) both paused; --o: 1; }

.ru-c {
    stroke: var(--accent);
    stroke-width: 1.5;
    fill: none;
    opacity: 0;
    animation: ru-corner 0.6s var(--ease-out) var(--d, 0s) both paused;
}

@keyframes ru-corner {
    from { opacity: 0; }
    to   { opacity: 0.9; }
}

.ru-core {
    fill: var(--accent);
    animation: a-pop 0.8s var(--ease-out) 1.6s both paused;
}

/* open: particles leave through the open edge */
.op-box, .op-edge { stroke: var(--line); stroke-width: 1; fill: none; }

.op-core { stroke: var(--rule); stroke-width: 1; }

.op-dot {
    fill: var(--accent);
    opacity: 0;
    --tx: 86px;
    animation: a-run 3.3s linear var(--d, 0s) infinite paused;
}

/* measure: bars grow on a baseline, a reading settles on top */
.me-base { stroke: var(--line); stroke-width: 1; }

.me-bar {
    stroke: var(--line);
    stroke-width: 1;
    transform-origin: center bottom;
    animation: me-grow 0.9s var(--ease-out) var(--d, 0s) both paused;
}

@keyframes me-grow {
    from { opacity: 0; transform: scaleY(0); }
    to   { opacity: 1; transform: scaleY(1); }
}

.me-read {
    stroke: var(--accent);
    stroke-width: 1.5;
    animation: ru-corner 0.6s var(--ease-out) 1.2s both paused;
}

.me-mark {
    fill: var(--accent);
    animation: a-pop 0.6s var(--ease-out) 1.4s both paused;
}

/* pair: the left square collects, the right one checks */
.pa-q, .pa-link { stroke: var(--line); stroke-width: 1; }

.pa-in {
    fill: var(--text-secondary);
    opacity: 0;
    --ty: 74px;
    animation: pa-drop 2.4s linear var(--d, 0s) infinite paused;
}

@keyframes pa-drop {
    0%   { opacity: 0; transform: translateY(0); }
    12%  { opacity: 0.7; }
    78%  { opacity: 0.7; }
    95%  { opacity: 0; transform: translateY(var(--ty)); }
    100% { opacity: 0; transform: translateY(var(--ty)); }
}

.pa-check {
    fill: none;
    stroke: var(--accent);
    stroke-width: 1.5;
    animation: a-pulse 3s ease-in-out infinite paused;
}

.pa-core {
    fill: var(--accent);
    animation: a-pop 0.8s var(--ease-out) 0.6s both paused;
}

/* ════ PRODUCT GLYPHS (reveal-triggered) ══════════════════════ */

/* engine: input compressed into a pulsing core */
.ge-frame { stroke: var(--rule); stroke-width: 1; }

.ge-core {
    fill: var(--accent);
    animation: a-pulse 3s ease-in-out infinite paused;
}

.ge-in {
    fill: var(--text-secondary);
    opacity: 0;
    animation: a-run 3s linear infinite paused;
}

.ge-in--l { --tx: 31px; }
.ge-in--r { --tx: -31px; animation-delay: 1.5s; }

/* format: entries appear cell by cell */
.gf-frame { stroke: var(--rule); stroke-width: 1; }

.gf-e {
    fill: var(--text-secondary);
    opacity: 0.7;
    animation: a-keep 0.5s var(--ease-out) var(--d, 0s) both paused;
    --o: 0.7;
}

.gf-e--sig { fill: var(--accent); --o: 1; }

/* registry: a package is filed into the shelf */
.gr-shelf { stroke: var(--rule); stroke-width: 1; }

.gr-have { fill: var(--text-tertiary); opacity: 0.7; }

.gr-pkg {
    fill: var(--accent);
    opacity: 0;
    animation: gr-file 5s linear infinite paused;
}

@keyframes gr-file {
    0%   { opacity: 0; transform: translateY(0); }
    10%  { opacity: 1; }
    55%  { opacity: 1; transform: translateY(58px); }
    80%  { opacity: 1; transform: translateY(58px); }
    92%  { opacity: 0; }
    100% { opacity: 0; transform: translateY(0); }
}

/* fabric: threads appear, the centre holds */
.gw-t {
    stroke: var(--line);
    stroke-width: 1;
    animation: ru-corner 0.5s var(--ease-out) var(--d, 0s) both paused;
}

.gw-n { stroke: var(--rule); stroke-width: 1; }

.gw-core {
    fill: var(--accent);
    animation: a-pop 0.7s var(--ease-out) 1.2s both paused;
}

/* ── start on reveal (section pieces + glyphs) ───────────────── */
.is-in .art rect,
.is-in .art line,
.is-in .art path { animation-play-state: running; }

/* ── no JS: hero pieces are pure CSS and keep running; section
   pieces never get .is-in, so show their end state instead ───── */
html:not(.js) .art:not(.art--live) rect,
html:not(.js) .art:not(.art--live) line,
html:not(.js) .art:not(.art--live) path { animation: none; }

html:not(.js) .af-s, html:not(.js) .al-b, html:not(.js) .ay-dot,
html:not(.js) .op-dot, html:not(.js) .pa-in, html:not(.js) .ge-in,
html:not(.js) .gr-pkg { opacity: 0; }

/* ── reduced motion: still image, end state ──────────────────── */
@media (prefers-reduced-motion: reduce) {
    .art rect, .art line, .art path { animation: none !important; }
    .al-b, .af-s, .ay-dot,
    .hx-b, .hs-dot, .hv-dot, .hc-dot, .hb-p, .hb-run,
    .op-dot, .pa-in, .ge-in, .gr-pkg, .hc-core { opacity: 0 !important; }
}
