/* THE WANT CARD'S FRONT, FROM HIS PEN SKETCH (Steven 2026-11-12, morning:
   "Where the 40% size needs to be the title of it ... below that will be
   the budget ... for the first dot, that's where the 40 is going to be,
   and the yellow dot we're going to put 100 beside it ... And then below
   that, we're going to put 40% but the text isn't going to be as large";
   templates/cards/_want_front.html). Top to bottom over the foot of the
   picture: the title big and fat with the budget under it, the thin rule,
   the line with its numbers at the dots, the agent's row once an agent is
   chosen, the number line, smaller. The top of the picture is clear (the
   round button top left, the three dots top right).

   The pieces carry their own classes (.tb-wf__titleblock, .tb-wf__title
   with its size step --xl/--l/--m/--s, .tb-wf__budget, .tb-wf__chart,
   .tb-chart__label, .tb-wf__odds) so another card can wear them. Inside
   the feed's want card the older rules for .tb-card__title, the chart and
   the big number are many classes deep (card.css, card-col.css,
   home-cards.css); the second selector of each rule here is as deep, so
   these win there without !important. */

/* ---- the block ---------------------------------------------------------- */
.tb-card .tb-card__over.tb-wf { gap: var(--space-2); }

/* the top of the picture is clear now: a light fade for the round button
   and the three dots only, then the picture, then the night under the
   title block (its ::before) */
.tb-card:is(.tb-card--want, .tb-card--offer) .tb-card__art--image:has(> .tb-card__over.tb-wf) > .tb-card__shade {
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--color-dark-900) 34%, transparent) 0%,
        transparent 16%,
        transparent 46%,
        color-mix(in srgb, var(--color-dark-900) 50%, transparent) 64%,
        color-mix(in srgb, var(--color-dark-900) 88%, transparent) 100%);
}

/* ---- the title and the budget -------------------------------------------- */
.tb-wf__titleblock {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
    flex: none;
    min-width: 0;
}
/* THE TITLE NEVER RUNS UNDER THE RIGHT COLUMN: on a card whose white
   part is tall (a pick between drafts) the title block rides up beside the
   heart, Share path and Flip; the title alone stops short of the discs,
   the chart and the number line under it keep the card's whole width */
.app-shell--deck-shell .tb-card--col :is(.tb-card__art > .tb-card__over.tb-wf, .tb-side__words) > .tb-wf__titleblock {
    padding-right: calc(var(--ds-col-right) + var(--ds-col) + var(--space-2) - var(--space-5));
}
/* the night under the title stays inside the picture: an offer's art did
   not clip, and the night ran down over the white part like a film
   (Steven 2026-11-12, dr-moose's "A storybook about you": "I cant see the
   cards") */
.tb-card .tb-card__art:has(> .tb-card__over.tb-wf) { overflow: hidden; }
/* THE TEXT READS ON ANY PICTURE: from a little above the title down, the
   picture goes to night (the odds' own shade in card.css, moved up to the
   title, which is the top of the block now) */
.tb-card:is(.tb-card--want, .tb-card--offer) .tb-card__art--image .tb-wf__titleblock::before {
    content: '';
    position: absolute;
    z-index: -1;
    top: -72px;
    left: calc(-1 * var(--space-5));
    right: calc(-1 * var(--space-5));
    height: 1600px;
    background: linear-gradient(180deg,
        transparent 0,
        color-mix(in srgb, var(--color-dark-900) 58%, transparent) 72px,
        color-mix(in srgb, var(--color-dark-900) 78%, transparent) 220px,
        color-mix(in srgb, var(--color-dark-900) 92%, transparent) 420px);
    pointer-events: none;
}
.tb-wf__title,
.tb-card:is(.tb-card--want, .tb-card--offer) :is(.tb-card__art .tb-card__over.tb-wf, .tb-side__words) > .tb-wf__titleblock > .tb-card__title.tb-wf__title.tb-wf__title {
    display: block;
    margin: 0;
    max-width: 100%;
    font-family: var(--font-heading);
    --interface-font: var(--font-heading);
    font-weight: 800;
    line-height: 1.02;
    letter-spacing: -0.03em;
    color: var(--text-inverse);
    text-shadow: 0 2px 18px rgb(0 0 0 / 0.5);
    /* never a cut word, never an ellipsis: the size steps down instead */
    overflow: visible;
    overflow-wrap: normal;
    word-break: normal;
    hyphens: manual;
    -webkit-line-clamp: none;
    line-clamp: none;
    -webkit-box-orient: initial;
    /* the title runs the card's width up to the right column, never
       balanced into two short lines (Steven 2026-11-12: "make sure this
       text spans the whole card") */
    text-wrap: wrap;
}
/* the size of the old big number ("41.0%"), stepping down with the
   title's length (want_title_size): a short title one line, a long one two
   or three, every word whole */
.tb-wf__title--xl,
.tb-card:is(.tb-card--want, .tb-card--offer) :is(.tb-card__art .tb-card__over.tb-wf, .tb-side__words) > .tb-wf__titleblock > .tb-card__title.tb-wf__title.tb-wf__title--xl { font-size: clamp(34px, 11vw, 48px); font-size: clamp(34px, 13cqi, 48px); }
.tb-wf__title--l,
.tb-card:is(.tb-card--want, .tb-card--offer) :is(.tb-card__art .tb-card__over.tb-wf, .tb-side__words) > .tb-wf__titleblock > .tb-card__title.tb-wf__title.tb-wf__title--l { font-size: clamp(30px, 9vw, 40px); font-size: clamp(30px, 10.6cqi, 40px); }
.tb-wf__title--m,
.tb-card:is(.tb-card--want, .tb-card--offer) :is(.tb-card__art .tb-card__over.tb-wf, .tb-side__words) > .tb-wf__titleblock > .tb-card__title.tb-wf__title.tb-wf__title--m { font-size: clamp(25px, 7.4vw, 32px); font-size: clamp(25px, 8.6cqi, 32px); }
.tb-wf__title--s,
.tb-card:is(.tb-card--want, .tb-card--offer) :is(.tb-card__art .tb-card__over.tb-wf, .tb-side__words) > .tb-wf__titleblock > .tb-card__title.tb-wf__title.tb-wf__title--s { font-size: clamp(22px, 6.4vw, 27px); font-size: clamp(22px, 7.2cqi, 27px); }
.tb-wf__title--xs,
.tb-card:is(.tb-card--want, .tb-card--offer) :is(.tb-card__art .tb-card__over.tb-wf, .tb-side__words) > .tb-wf__titleblock > .tb-card__title.tb-wf__title.tb-wf__title--xs { font-size: clamp(19px, 5.4vw, 22px); font-size: clamp(19px, 6cqi, 22px); line-height: 1.08; }
.tb-wf__budget,
.tb-card:is(.tb-card--want, .tb-card--offer) :is(.tb-card__art .tb-card__over.tb-wf, .tb-side__words) > .tb-wf__titleblock > .tb-card__budget.tb-wf__budget {
    color: color-mix(in srgb, var(--text-inverse) 84%, transparent);
    font-size: var(--text-base);
    line-height: var(--leading-snug);
    white-space: nowrap;
    text-shadow: 0 1px 12px rgb(0 0 0 / 0.45);
}
.tb-card--want .tb-card__art--image .tb-wf__odds :is(.tb-card__number, .tb-card__caption) { text-shadow: 0 1px 12px rgb(0 0 0 / 0.45); }

/* ---- the chart with its numbers at the dots ----------------------------- */
.tb-wf__chart,
.tb-card .tb-card__art .tb-card__over.tb-wf > svg.tb-card__chart.tb-wf__chart {
    display: block;
    flex: none;
    width: 100%;
    height: auto;
    min-height: 0;
    max-height: none;
    margin: 0;
    overflow: visible;
    background: none;
}
/* the two thin rules the line sits between (Steven 2026-11-12: "put a
   line at the bottom of the chart that matches the top"), one look */
.tb-chart__rule { stroke: color-mix(in srgb, var(--text-inverse) 34%, transparent); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.tb-chart__label {
    fill: var(--text-inverse);
    font-family: var(--font-heading);
    /* a clear step under the old 27 (Steven 2026-11-12: "the text on the
       numbers need to be smaller"): about 12px on a phone's card */
    font-size: 21px;
    font-weight: 600;
    letter-spacing: -0.01em;
    paint-order: stroke;
    stroke: rgb(0 0 0 / 0.35);
    stroke-width: 4px;
    stroke-linejoin: round;
    pointer-events: none;
}
/* the tapped dot's words take the line's foot; the numbers stay put */
.tb-card .tb-card__over.tb-wf > .tb-card__markers.tb-wf__foot { display: block; min-height: 0; }
/* with no agent the foot holds only the dot's words: it takes no room */
.tb-card .tb-card__over.tb-wf > .tb-card__markers.tb-wf__foot:not(.tb-wf__foot--agent) { height: 0; margin-top: calc(-1 * var(--space-2)); }
/* THE AGENT GROUP (Steven 2026-11-12, "we need to move the NIA group
   here"): in the chart's own strip (want_chart grows its box by 84 of its
   640 for it), left-aligned, just above the bottom rule; the round in the
   purple ring, the name bold, "with <mark> Opus" under it. */
.tb-card .tb-card__over.tb-wf > .tb-card__markers.tb-wf__foot.tb-wf__foot--agent {
    display: flex;
    justify-content: flex-start;
    margin-top: calc(-84 / 640 * 100cqi - var(--space-2) + 4px);
    margin-bottom: 4px;
    position: relative;
}
.tb-card .tb-card__over.tb-wf > .tb-card__markers.tb-wf__foot--agent > .tb-card__chart-agent {
    max-width: 100%;
    justify-self: start;
    gap: var(--space-2);
    color: var(--text-inverse);
    text-align: left;
}
.tb-card .tb-wf__foot--agent .tb-card__chart-face {
    width: 40px;
    height: 40px;
    border: 2px solid var(--tb-card-purple, var(--color-purple-500));
    box-shadow: 0 0 0 1px rgb(0 0 0 / 0.25);
}
.tb-card .tb-wf__foot--agent .tb-card__chart-name { font-size: var(--text-base); font-weight: 800; color: var(--text-inverse); line-height: 1.15; }
.tb-card .tb-wf__foot--agent .tb-card__chart-model {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: var(--font-mono);
    --interface-font: var(--font-mono);
    font-size: var(--text-xs);
    opacity: 0.9;
}
.tb-card .tb-wf__foot--agent .tb-card__chart-mark { font-size: 14px; }
.tb-card .tb-card__over.tb-wf > .tb-card__markers.tb-wf__foot:not(.tb-wf__foot--agent) .tb-card__dotnote { bottom: auto; top: 0; }

/* ---- the number line, smaller, under the chart -------------------------- */
.tb-wf__odds,
.tb-card:is(.tb-card--want, .tb-card--offer) .tb-card__art .tb-card__over.tb-wf > .tb-wf__odds {
    display: flex;
    flex: none;
    flex-wrap: nowrap;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
}
.tb-wf__number,
.tb-card:is(.tb-card--want, .tb-card--offer) .tb-card__art .tb-card__over.tb-wf > .tb-wf__odds > .tb-card__number.tb-wf__number {
    flex: none;
    font-size: 28px;
    line-height: 1;
    letter-spacing: -0.03em;
    white-space: nowrap;
}
.tb-wf__oddsside,
.tb-card:is(.tb-card--want, .tb-card--offer) .tb-card__art .tb-card__over.tb-wf > .tb-wf__odds > .tb-card__oddsside.tb-wf__oddsside {
    flex: 1 1 auto;
    min-width: 0;
    gap: 2px;
}
.tb-card:is(.tb-card--want, .tb-card--offer) .tb-card__art .tb-card__over.tb-wf > .tb-wf__odds .tb-card__chips { gap: var(--space-1); }
.tb-card:is(.tb-card--want, .tb-card--offer) .tb-card__art .tb-card__over.tb-wf > .tb-wf__odds :is(.tb-card__move, .tb-card__band, .tb-card__chip) {
    padding: 1px var(--space-2);
    font-size: var(--text-xs);
}
.tb-card:is(.tb-card--want, .tb-card--offer) .tb-card__art .tb-card__over.tb-wf > .tb-wf__odds .tb-card__caption {
    font-size: var(--text-sm);
    line-height: 1.2;
    white-space: nowrap;
}

/* ---- the picture that is still coming ----------------------------------- */
/* ONE PICTURE PER WANT (Steven 2026-11-12: "this card after I said I want a
   free house is switched images"): while the want's own picture is drawn
   (home_cards.card_art, `art_coming`) the card wears a quiet night with a
   slow light across it, never a stand-in photograph it would trade away a
   moment later. Its picture comes in once, when it lands. */
.tb-wf__coming {
    position: absolute;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    background:
        radial-gradient(120% 70% at 50% 30%, color-mix(in srgb, var(--color-dark-700) 70%, transparent), transparent 70%),
        var(--tb-card-night, var(--color-dark-900));
}
.tb-wf__coming::after {
    content: '';
    position: absolute;
    inset: -20% -60%;
    background: linear-gradient(100deg, transparent 40%, rgb(255 255 255 / 0.06) 50%, transparent 60%);
    animation: tb-wf-coming 2.8s ease-in-out infinite;
}
@keyframes tb-wf-coming { from { transform: translateX(-40%); } to { transform: translateX(40%); } }
@media (prefers-reduced-motion: reduce) {
    .tb-wf__coming::after { animation: none; }
}

/* ---- the right column clears the words ---------------------------------- */
/* THE DISCS RIDE THE PICTURE, UNDER THE THREE DOTS: the want's words now
   fill the foot of its picture from edge to edge (the title, the line with
   the yellow target and its "100%" at the right end), where the column's
   discs used to stand at the card's middle and covered the target and its
   number. On a want card wearing this front the heart, Share path and Flip
   stand at the top of the right edge, one column gap under the three
   dots' round (card-col.css), over the clear picture; the same place on its back (they ride the card's frame). */
.app-shell--deck-shell .tb-card--col:is(.tb-card--want, .tb-card--offer):has(> .tb-card__inner > .tb-card__front .tb-wf__titleblock) > .tb-card__col {
    justify-content: flex-start;
    padding-top: calc(var(--space-4) + var(--ds-col) + var(--ds-col-gap));
}
/* a pack's card wears Approve all (the thumbs up, heat-stacks.css) under
   the three dots: the heart, Share path and Flip stand one disc lower, so
   nothing a person could press before is covered */
.app-shell--deck-shell .tb-card--col:is(.tb-card--want, .tb-card--offer):has(> .tb-card__inner > .tb-card__front .tb-wf__titleblock) > .tb-card__col:has(> .hc-pack-approve:not([hidden])) {
    padding-top: calc(var(--space-4) + 2 * (var(--ds-col) + var(--ds-col-gap)));
}

/* ---- Save card beside DELIVERED ----------------------------------------- */
/* (Steven 2026-11-12: "save card should be BESIDE delivered."): the deck
   shell puts the Save card button on the DELIVERED pill's row
   (deck-shell.js bmSaveCard, .tb-card__kickrow--save), to its right and
   centred with it; the record line ("<agent> delivered · free · Nov 12")
   runs under that row at its full width. Under 360 wide the button keeps
   its heart and drops its word, never wrapping under the pill. */
.tb-card__kickrow.tb-card__kickrow--save { flex-wrap: nowrap; align-items: center; }
.tb-card__kickrow--save > .tb-card__save { flex: none; }
@media (max-width: 359.98px) {
    .tb-card__kickrow--save > .tb-card__save [data-tb-save-card-words] { display: none; }
    .tb-card__kickrow--save > .tb-card__save { padding: 0 var(--space-2); }
}

/* ---- the market card's cover (Steven 2026-11-12: "This is the cover card
   for ANY want that is in the market."): the title big and low, the price
   in the budget's place, then the agent's row (its round, "By Nia", the
   certification chip) under them, no chart ------------------------------- */
.tb-card .tb-card__over.tb-wf.tb-wf--offer > .tb-card__byline--foot { margin-top: var(--space-1); }
.tb-card .tb-card__over.tb-wf.tb-wf--offer > .tb-wf__titleblock > .tb-wf__budget { font-weight: 600; color: var(--text-inverse); }

/* ---- the agent's turn front: the title where the name was --------------- */
/* (Steven 2026-11-12, "Find your Seattle dog": "The Title Where bree is, and
   agents turn is the right look"): under the AGENT'S TURN pill the want's
   title big (cards/_agent_side.html `low`), then "Bree · Writing your plan"
   and the box as before */
.tb-side__words > .tb-wf__titleblock { margin: 0 0 var(--space-2); }
.tb-side__state .tb-side__statename { font-weight: 700; color: var(--text-inverse); }
.tb-side__state .tb-side__statename a { color: inherit; text-decoration: none; }

/* ---- THE GATHERING PILL -------------------------------------------------- */
/* (Steven 2026-11-12: "Gathering proposals should do the same thing"): the
   step's ring "1" and GATHERING PROPOSALS in the AGENT'S TURN pill's own
   look (heat-stacks.css, the cyan label with its still halo and the slow
   glow), over the title; the cyan is the colour that already means
   Gathering (the pip, the old cyan words). */
.tb-wf__pillrow { display: flex; align-items: center; margin-bottom: var(--space-2); }
.tb-wf__pillrow .tb-card__num {
    background: color-mix(in srgb, var(--color-dark-900) 45%, transparent);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    color: var(--text-inverse);
}
.tb-wf__pillrow .tb-card__kicker--agent .tb-card__label {
    position: relative;
    background: var(--color-cyan-500);
    color: var(--tb-ink, var(--color-dark-900));
    box-shadow: 0 0 var(--space-2) var(--color-cyan-500);
}
.tb-wf__pillrow .tb-card__kicker--agent .tb-card__label::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow: 0 0 var(--space-5) var(--space-1) var(--color-cyan-500);
    opacity: 0;
    pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
    .tb-wf__pillrow .tb-card__kicker--agent .tb-card__label::after { animation: tb-wf-glow calc(var(--duration-slow) * 8) ease-in-out infinite; will-change: opacity; }
}
@keyframes tb-wf-glow { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }

/* ---- MORE OF THE OFFER'S WORDS ON THE FRONT ------------------------------ */
/* (Steven 2026-11-12, "Your superheroes song" with its words cut to one
   line: "We need to give more text for the pdp page, and then the back is
   the very detailed page and purchase."): on a market card's front the
   offer's description shows four lines (five on a tall phone), whole words,
   "..." only when it runs longer; the picture gives up the height, the
   title block stays low on it, nothing goes under the bottom buttons. The
   back is the detailed page and the purchase (not this file). */
.hc-slide .tb-card.tb-card--offer:has(.tb-card__over.tb-wf--offer) > .tb-card__inner > .tb-card__front > .tb-card__panel .tb-card__body {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    overflow: hidden;
    overflow-wrap: normal;
    word-break: normal;
}
@media (min-height: 820px) {
    .hc-slide .tb-card.tb-card--offer:has(.tb-card__over.tb-wf--offer) > .tb-card__inner > .tb-card__front > .tb-card__panel .tb-card__body { -webkit-line-clamp: 5; line-clamp: 5; }
}
.hc-slide .tb-card.tb-card--offer:has(.tb-card__over.tb-wf--offer) > .tb-card__inner > .tb-card__front > .tb-card__panel { flex: none; }
.hc-slide .tb-card.tb-card--offer:has(.tb-card__over.tb-wf--offer) > .tb-card__inner > .tb-card__front > .tb-card__art { flex: 1 1 0; min-height: 0; }

/* THE AGENT GROUP ON THE BACK (Steven 2026-11-12: "Nia goes on back"): above
   the plan on a plan card's back (cards/_card.html _plan_back,
   [data-tb-card-planagent]), in the back's own ink; the front has none */
.tb-card .tb-card__planagent { display: flex; align-items: center; padding: var(--space-3) var(--space-5) 0; }
.tb-card .tb-card__planagent > .tb-card__chart-agent { display: inline-flex; align-items: center; gap: var(--space-2); justify-self: start; text-align: left; color: var(--text-primary); }
.tb-card .tb-card__planagent .tb-card__chart-name { color: var(--text-primary); }
.tb-card .tb-card__planagent .tb-card__chart-model { color: var(--text-secondary); opacity: 1; }
