/* =============================================================================
   THE TEAM PAGES' SURFACE

   One skin for the whole team-building family: /team-builder/ (where a build is
   made), the four pages that HOST builds — /arena-teams/, /guild-boss/,
   /cookie-alliance/ and the per-event pages at /events/{event-id}/ — and the
   permanent per-build pages under each of those (/arena-teams/builds/{slug}/
   and its siblings), which are documents rather than app pages and consume the
   tokens from an inline stylesheet of their own.

   Why a file and not five copies. Those five surfaces were built at different
   times against different palettes: the two hubs painted a blurred screenshot
   of the game behind everything and filled their build cards with the Cookie
   rarity gradients (a dark red for Arena, a pale teal for Guild Boss); Cookie
   Alliance inherited feature-page.css's magenta body wash and tinted its cards
   cyan; the event pages framed nothing at all. Read one after another they did
   not look like one site, and a build posted from the builder arrived wearing a
   colour it had never worn while it was being made.

   The values below are the BUILDER's, lifted verbatim from
   team-builder/styles.css, which now consumes them from here rather than
   restating them — so "the builder's look" has exactly one definition and the
   hosting pages cannot drift from it. Retune a token here and all five move
   together.

   WHAT THIS FILE MOSTLY DOES NOT DO. It declares tokens and the category tones;
   each route's own stylesheet applies them to ITS selectors, because the four
   hosting pages render their cards from four different app.js files with four
   different class names, and rewriting that markup to share a class would be a
   far bigger change than making the pages look alike.

   Three things it DOES paint, each because duplicating it five times is exactly
   what this file exists to stop: the page gutter, the collection grid's column
   ladder, and the link list the community-build bake writes. All three name
   each page's own selector rather than a shared class — there is no class to
   add without editing generated markup, and a class nothing emits is dead.

   LOAD ORDER. Link this BEFORE the route's own styles.css, so a route can
   still override a token or a rule for a case this file does not cover.

   Cache busting is manual (see CLAUDE.md): this file is served immutable for a
   year under its ?v= tag, so bump the tag on EVERY page that links it whenever
   it changes. SIX places, four hand-written and two generators:
     www/team-builder/index.html, www/arena-teams/index.html,
     www/guild-boss/index.html, www/cookie-alliance/index.html,
     www/scripts/bake-events.mjs — reads the tag off /team-builder/index.html,
       so bumping the builder carries it to every per-event page on a re-bake
     www/scripts/bake-community-builds.mjs — TEAM_SURFACE_CSS, a literal, so it
       has to be bumped by hand and the permanent per-build pages re-baked
   ========================================================================== */

:root {
  /* ── Panel ────────────────────────────────────────────────────────────
     The builder's numbered section (.tb-panel). A hosting page's equivalent
     is whatever section wraps its community list — .guild-boss-card on the
     hubs, .ca-overview / .ca-teams on Cookie Alliance, the community-teams
     section on an event page.

     The background is a gradient rather than a flat fill so a tall panel is
     not a single slab of colour; the shadow is the shared --tcb-shadow, which
     is what lifts a panel off --tcb-page-backdrop rather than a border alone. */
  --tbs-panel-line: var(--tcb-line);
  --tbs-panel-radius: 1.1rem;
  --tbs-panel-bg: linear-gradient(150deg, rgba(28, 23, 45, 0.72), rgba(17, 13, 27, 0.92));
  --tbs-panel-shadow: var(--tcb-shadow);
  --tbs-panel-pad: clamp(1rem, 2.2vw, 1.4rem);
  --tbs-panel-gap: 1rem;

  /* The panel's heading and its one-line note. The builder sets its section
     titles in the game's own face and keeps them SENTENCE case at a modest
     size — the hubs shouted theirs in 1.62rem uppercase with a three-layer
     text shadow, which read as a page title rather than as a section head. */
  --tbs-panel-title-font: "CookieRun KR", "Outfit", sans-serif;
  --tbs-panel-title-size: clamp(1.05rem, 2.2vw, 1.3rem);
  --tbs-panel-note-size: 0.9rem;

  /* ── Build card ───────────────────────────────────────────────────────
     One saved/posted build, collapsed. The border is 2px rather than a
     hairline because it carries the build's CATEGORY colour and has to read
     as a deliberate edge; --tbs-card-line is the neutral fallback for a card
     whose category is unknown, and a toned card overrides it below. */
  --tbs-card-line: var(--tcb-line);
  --tbs-card-border-width: 2px;
  --tbs-card-radius: 0.9rem;
  --tbs-card-bg: rgba(23, 20, 37, 0.72);
  --tbs-card-pad: 0.75rem 0.9rem;
  --tbs-card-gap-x: 0.8rem;
  --tbs-card-gap-y: 0.5rem;

  /* The grid a collection of cards sits in. Column counts are STATED at each
     step rather than packed by auto-fit, for the reason the builder's own
     collection states them: a packing algorithm picks the count from a
     minimum track width, so the card's width at each breakpoint is whatever
     falls out — and the card changes its own layout by width, so "whatever
     falls out" is a layout nobody looked at. Stated, the narrowest card is
     ~345-365px at every count, so there is ONE narrow card to design for. */
  --tbs-collection-gap: 0.75rem;

  /* ── Pills ────────────────────────────────────────────────────────────
     The little status/meta chips on a card (category, context, visibility,
     team count). */
  --tbs-pill-pad: 0.15rem 0.5rem;
  --tbs-pill-radius: 999px;
  --tbs-pill-size: 0.74rem;

  /* ── Roster portraits ─────────────────────────────────────────────────
     SQUARE, in a square frame — the tiles in the builder above show the same
     slug-named square portraits, and the hosting pages were the one place on
     the site that cropped them to circles. `contain` rather than `cover`: the
     assets are 160x160 so the two are identical today, and contain is the one
     that cannot crop a future asset that is not. */
  --tbs-portrait-size: 2.1rem;
  --tbs-portrait-radius: 0.45rem;
  --tbs-portrait-line: var(--tcb-line);
  --tbs-portrait-bg: var(--tcb-surface-strong);

  /* ── Controls ─────────────────────────────────────────────────────────
     Small buttons that sit on a card (a toggle, a menu item). */
  --tbs-control-radius: 0.6rem;
  --tbs-control-line: var(--tcb-line);
  --tbs-control-bg: var(--tcb-surface-strong);

  /* ── The page's own gutter and rhythm ─────────────────────────────────
     What <main> puts between the panels and around them. feature-page.css's
     .route-main gives every page 1rem/0.5rem and a flat 2rem gap; the builder
     states its own, and the three hosting pages whose WHOLE page is the
     hosting page now read the same two numbers, so a panel sits the same
     distance from the window edge on all four.

     Not applied to /events/{id}/: only one section of an event page hosts
     builds, and its gutter is the event page's, shared with its own content. */
  --tbs-main-pad: clamp(1rem, 3vw, 2.4rem) clamp(0.9rem, 3vw, 2rem) 4rem;
  --tbs-main-gap: clamp(1.2rem, 2.6vw, 1.8rem);
}

/* =============================================================================
   CATEGORY TONES

   The site's seven content categories in the colours the Community Guides page
   gives them, so one category reads the same wherever it appears. These moved
   here from team-builder/styles.css, which was their only home while the
   builder was their only consumer; a hosting page IS one of these categories
   from end to end, so its build cards now wear the same edge the same build
   wears in the builder's own collection.

   STILL COPIED, not shared, from `.guide-category-tone--*` in
   community-guides/styles.css — pulling the winning half of a two-layer cascade
   out of a 5,000-line route stylesheet is a bigger change than this is worth,
   so a colour retuned there still has to be retuned here. The category LIST is
   genuinely shared, in assets/js/site-categories.js. Cookie Alliance's
   styles.css also names its accent (--ca-accent) from this table; the comment
   there says so.

   Applied two ways, because the builder and the hosting pages know different
   things at render time:

     · by CLASS — `tb-cat-tone--{id}`, which team-builder/app.js puts on its
       chips, team blocks and saved-build rows, and events/community-teams.js
       puts on a card from the build's own stored category.

     · by ROUTE — a hosting page is a single category from end to end, and its
       cards come out of app.js files that know nothing about these classes.
       Declaring the tone on the body means every card, badge and frame on the
       page can read `--tb-cat-rgb` with no markup change at all. Nothing else
       on the site consumes `--tb-cat-*`, so inheriting it page-wide is inert
       everywhere it is not asked for.

   `--tb-cat-rgb` is the same colour as `--tb-cat-line`/`--tb-cat-glow` held as
   a bare channel triplet, so a consumer can pick its own alpha with
   `rgb(var(--tb-cat-rgb) / a)` instead of needing a new pre-mixed rgba() per
   opacity. Retuning a tone means retuning it too.
   ========================================================================== */
.tb-cat-tone--arena,
body[data-route="arena-teams"] {
  --tb-cat-fill: linear-gradient(135deg, #ff5fa2, #c0246b);
  --tb-cat-line: rgba(255, 95, 162, 0.7);
  --tb-cat-glow: rgba(255, 95, 162, 0.28);
  --tb-cat-rgb: 255 95 162;
}

.tb-cat-tone--guild-boss,
body[data-route="guild-boss"] {
  --tb-cat-fill: linear-gradient(135deg, #ff7a45, #c2410c);
  --tb-cat-line: rgba(255, 122, 69, 0.7);
  --tb-cat-glow: rgba(255, 122, 69, 0.28);
  --tb-cat-rgb: 255 122 69;
}

.tb-cat-tone--story-campaign {
  --tb-cat-fill: linear-gradient(135deg, #5cc98a, #1f8a52);
  --tb-cat-line: rgba(92, 201, 138, 0.72);
  --tb-cat-glow: rgba(92, 201, 138, 0.26);
  --tb-cat-rgb: 92 201 138;
}

.tb-cat-tone--cookie-alliance,
body[data-route="cookie-alliance"] {
  --tb-cat-fill: linear-gradient(135deg, #22b8e6, #0e7490);
  --tb-cat-line: rgba(34, 184, 230, 0.72);
  --tb-cat-glow: rgba(34, 184, 230, 0.26);
  --tb-cat-rgb: 34 184 230;
}

.tb-cat-tone--cake-towers {
  --tb-cat-fill: linear-gradient(135deg, #b574ff, #7e22ce);
  --tb-cat-line: rgba(181, 116, 255, 0.72);
  --tb-cat-glow: rgba(181, 116, 255, 0.26);
  --tb-cat-rgb: 181 116 255;
}

/* An EVENT page, not the /events/ hub: `events-event-page` is the class
   bake-events.mjs puts on a per-event page's body, and only those host builds.
   A story event's page still defaults to the Events amber here and a story
   build posted to it overrides to green through its own tone class — the page
   is the fallback, the build's stored category is the answer. */
.tb-cat-tone--events,
body[data-route="events"].events-event-page {
  --tb-cat-fill: linear-gradient(135deg, #f5a623, #b8780c);
  --tb-cat-line: rgba(245, 166, 35, 0.72);
  --tb-cat-glow: rgba(245, 166, 35, 0.28);
  --tb-cat-rgb: 245 166 35;
}

.tb-cat-tone--other {
  --tb-cat-fill: linear-gradient(135deg, #94a3b8, #586577);
  --tb-cat-line: rgba(148, 163, 184, 0.7);
  --tb-cat-glow: rgba(148, 163, 184, 0.22);
  --tb-cat-rgb: 148 163 184;
}

/* =============================================================================
   THE TWO RULE SETS THIS FILE DOES PAINT

   Everything else is applied by each route to its own selectors. These two are
   here because they are pure geometry with no route-specific markup around
   them, and duplicating them five times is exactly what this file exists to
   stop.
   ========================================================================== */

/* ── The page gutter ─────────────────────────────────────────────────────
   <main> on the three pages whose whole page hosts builds, plus the builder's
   own. Same reason the ladder below names each page's selector: what matters
   is that the number is one number, and none of these containers shares a
   class. Only padding and gap — `display` is left alone, because the hubs and
   Cookie Alliance lay their sections out on a GRID and Cookie Alliance's
   .ca-overview carries a `min-width: 0` that exists precisely because it is a
   grid item. */
.team-builder-main,
body[data-route="arena-teams"] .route-main,
body[data-route="guild-boss"] .route-main,
body[data-route="cookie-alliance"] .route-main {
  padding: var(--tbs-main-pad);
  gap: var(--tbs-main-gap);
}

/* ── The baked "Community … Teams" link list ──────────────────────────────
   The SEO half of the community-build pipeline: a list of the permanent pages
   npm run bake:community-builds writes, dropped between markers into each hub
   and each event page by www/scripts/bake-community-builds.mjs.

   Its chrome is here rather than in any route stylesheet because ONE generator
   writes it into three hubs plus every event page, and it should look the same
   in all of them. The markup carries `.premium-glass` and an `.accent-*`, so
   these rules are overriding feature-page.css exactly as each route does for
   its own sections — same tokens, same result.

   The bake used to carry the padding and radius as an inline style attribute
   and the type sizes on each child, which no stylesheet could reach. Those are
   gone from the generator and from the pages it had already written; the one
   thing it still writes inline is the link colour, which is genuinely per-kind
   (pink on Arena, blue on Guild Boss, cyan on Cookie Alliance). Change the
   markup here and change it in that generator in the same commit, or the next
   daily bake will undo you. */
.community-team-pages {
  margin-top: 0;
  padding: var(--tbs-panel-pad);
  border: 1px solid var(--tbs-panel-line);
  border-radius: var(--tbs-panel-radius);
  background: var(--tbs-panel-bg);
  box-shadow: var(--tbs-panel-shadow);
}

.community-team-pages h2 {
  margin: 0 0 0.35rem;
  font-family: var(--tbs-panel-title-font);
  font-size: var(--tbs-panel-title-size);
  color: var(--tcb-ink);
}

.community-team-pages > p {
  margin: 0 0 0.7rem;
  color: var(--tcb-ink-soft);
  font-size: var(--tbs-panel-note-size);
  line-height: 1.5;
  max-width: 62ch;
}

.community-team-pages ul {
  margin: 0;
  padding-left: 1.25rem;
  font-size: 0.95rem;
  line-height: 1.9;
}

/* The credit and date after each link. */
.community-team-pages li > span {
  opacity: 0.75;
  font-size: 0.88em;
}

/* The collection grid's column ladder — one to four columns, stepping at 800,
   1180 and 1520px.

   Named for each page's own grid rather than applied by a shared class, for
   the reason the tones above are declared by route: the hubs build their grid
   in a 320KB app.js that knows nothing about this file, and adding a class
   there would buy nothing the selector list does not. The point of the ladder
   is that all five pages step at the SAME widths. Every threshold lands
   the narrowest card at ~345-365px, so there is one narrow card to design for
   wherever a build is shown.

   @media, deliberately, while a CARD's own layout is @container — the two do
   not have to agree, and that is the point: the grid decides how many columns
   the viewport affords, then each card measures itself and picks its layout
   from its OWN width. Retune a column count and nothing has to know what it
   did to the cards.

   Cookie Alliance and the event pages are deliberately NOT here. Their lists
   stay a single stacked column: an Alliance card holds three teams and an
   event card expands the full .tb-team preview in place, so a second column
   would halve the width the thing they exist to show gets. */
.tb-collection,
body[data-route="arena-teams"] .guild-team-build-saved-grid,
body[data-route="guild-boss"] .guild-team-build-saved-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--tbs-collection-gap);
  align-content: start;
}

@media (min-width: 800px) {
  .tb-collection,
  body[data-route="arena-teams"] .guild-team-build-saved-grid,
  body[data-route="guild-boss"] .guild-team-build-saved-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1180px) {
  .tb-collection,
  body[data-route="arena-teams"] .guild-team-build-saved-grid,
  body[data-route="guild-boss"] .guild-team-build-saved-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 1520px) {
  .tb-collection,
  body[data-route="arena-teams"] .guild-team-build-saved-grid,
  body[data-route="guild-boss"] .guild-team-build-saved-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
