/* CAFlirary visual primitives — one treatment per entity kind, shared by every
   surface. Competitions and teams carry no provider artwork (measured: 0%), so
   their treatment is deliberately a CAF design device rather than anything that
   could be mistaken for an official badge. */

:root {
  --caf-nav-1: #061423;
  --caf-nav-2: #0b1b2b;
  --caf-nav-3: #10243a;
  --caf-au: #d7a73d;
  --caf-au-2: #e3b94f;
  --caf-gr: #007a3d;
  --caf-gr-2: #009e55;
}

/* ── Tones: a stable accent per entity name, no storage needed ─────────── */
.caf-tone-gold { --tone-a: #d7a73d; --tone-b: #8a6516; }
.caf-tone-green { --tone-a: #009e55; --tone-b: #05502c; }
.caf-tone-navy { --tone-a: #2f6ea8; --tone-b: #10243a; }

/* Category accents. These are chosen from the words CAF uses in the official
   competition name — women's, futsal, beach soccer, U-17, Champions League,
   Africa Cup of Nations — so two Women's competitions look related and a
   futsal tournament does not look like a club one. A name that states no
   category keeps the neutral hash tone above; nothing here invents an
   identity mark. */
.caf-tone-women  { --tone-a: #b0559b; --tone-b: #4a1f42; }
.caf-tone-futsal { --tone-a: #e2803a; --tone-b: #6a3312; }
.caf-tone-beach  { --tone-a: #2fa8a0; --tone-b: #10403d; }
.caf-tone-youth  { --tone-a: #5e8ede; --tone-b: #1c3358; }
.caf-tone-club   { --tone-a: #d7a73d; --tone-b: #6b4f13; }
.caf-tone-nations{ --tone-a: #009e55; --tone-b: #05502c; }

/* ── Player avatar ─────────────────────────────────────────────────────── */
.caf-avatar {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border-radius: 50%;
  overflow: hidden;
  background: linear-gradient(150deg, var(--caf-nav-3), var(--caf-nav-1));
  border: 1px solid rgba(215, 167, 61, 0.28);
  color: var(--caf-au);
  font-weight: 800;
  letter-spacing: 0.3px;
}

.caf-avatar-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

.caf-avatar-xs { width: 22px; height: 22px; font-size: 8.5px; }
.caf-avatar-sm { width: 30px; height: 30px; font-size: 10px; }
.caf-avatar-md { width: 44px; height: 44px; font-size: 14px; }
.caf-avatar-lg { width: 84px; height: 84px; font-size: 26px; }
.caf-avatar-xl { width: 112px; height: 112px; font-size: 34px; }

/* ── Team mark ─────────────────────────────────────────────────────────── */
.caf-crest {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border-radius: 12px;
  background: linear-gradient(150deg, var(--tone-a, #d7a73d) -40%, var(--caf-nav-1) 72%);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: #ffffff;
  font-weight: 800;
  letter-spacing: 0.5px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

.caf-crest-sm { width: 30px; height: 30px; border-radius: 8px; font-size: 11px; }
.caf-crest-md { width: 46px; height: 46px; font-size: 15px; }
.caf-crest-lg { width: 76px; height: 76px; border-radius: 16px; font-size: 24px; }
.caf-crest-xl { width: 104px; height: 104px; border-radius: 20px; font-size: 32px; }

/* ── Competition artwork ───────────────────────────────────────────────── */
.caf-artwork {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 12px;
  overflow: hidden;
  background:
    radial-gradient(120% 140% at 12% 8%, rgba(255, 255, 255, 0.14) 0%, transparent 46%),
    linear-gradient(145deg, var(--tone-a, #d7a73d) -30%, var(--caf-nav-2) 58%, var(--caf-nav-1) 100%);
}

.caf-artwork.is-compact { aspect-ratio: 1 / 1; border-radius: 10px; }

/* A restrained geometric field, not a photograph and not a badge. */
.caf-artwork-pattern {
  position: absolute;
  inset: 0;
  opacity: 0.5;
  background-image: repeating-linear-gradient(115deg, rgba(255, 255, 255, 0.06) 0 1px, transparent 1px 24px);
}

/* One title band, the same height on every card, with the text sitting on its
   baseline. Previously the mark was anchored to the bottom of the artwork and
   grew upward, so a one-line name and a three-line name started at different
   heights and the grid read as ragged. Reserving the band keeps every card's
   name, qualifier and facts on the same lines across a row. */
/* Plain block: the box is absolutely positioned against the artwork's bottom
   edge, so every card's text already ends on the same line regardless of how
   many lines it takes. Flex and a reserved min-height would add nothing. */
.caf-artwork-text {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 13px;
  display: block;
  font-size: clamp(16px, 1.6vw, 22px);
}

.caf-artwork-mark {
  font-size: 1em;
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: 0.2px;
  color: #ffffff;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.45);
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* The part of the official name after CAF's own separator — a host country or
   edition. On its own line it stops the name clamping to a dangling hyphen. */
.caf-artwork-qualifier {
  display: block;
  margin-top: 3px;
  font-size: 0.62em;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: rgba(255, 255, 255, 0.82);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* A quiet category cue, not a badge and not a crest. */
.caf-artwork-glyph {
  position: absolute;
  left: 15px;
  top: 12px;
  font-size: 17px;
  line-height: 1;
  color: rgba(255, 255, 255, 0.5);
}

.caf-artwork-season {
  position: absolute;
  right: 12px;
  top: 11px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: 0.7px;
  color: #061423;
  background: var(--caf-au);
  padding: 3px 9px;
  border-radius: 999px;
}

.caf-artwork.is-compact .caf-artwork-text {
  left: 10px;
  right: 10px;
  bottom: 8px;
  font-size: 20px;
}

/* ── Media thumbnail ───────────────────────────────────────────────────── */
.caf-thumb {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 9px;
  overflow: hidden;
  background: var(--caf-nav-3);
}

.caf-thumb-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.caf-thumb-fallback {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(150deg, var(--caf-nav-3), var(--caf-nav-1));
}

.caf-thumb-glyph { font-size: 20px; color: rgba(215, 167, 61, 0.7); }

.caf-thumb-badge,
.caf-thumb-corner {
  position: absolute;
  bottom: 6px;
  font-size: 10px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  background: rgba(6, 20, 35, 0.86);
  color: #e8eff6;
}

.caf-thumb-badge { left: 6px; }
.caf-thumb-corner { right: 6px; font-family: 'SF Mono', 'Consolas', monospace; }

/* ── Collection mosaic, built from current real results ────────────────── */
.caf-mosaic {
  position: relative;
  display: grid;
  width: 100%;
  aspect-ratio: 16 / 9;
  gap: 2px;
  border-radius: 11px;
  overflow: hidden;
  background: var(--caf-nav-1);
}

.caf-mosaic-1 { grid-template-columns: 1fr; }
.caf-mosaic-2 { grid-template-columns: 1fr 1fr; }
.caf-mosaic-3 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }
.caf-mosaic-3 .caf-mosaic-cell:first-child { grid-row: span 2; }
.caf-mosaic-4 { grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; }

.caf-mosaic-cell { position: relative; overflow: hidden; }
.caf-mosaic-cell .caf-thumb { height: 100%; aspect-ratio: auto; border-radius: 0; }

.caf-mosaic.is-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(145deg, var(--tone-a, #d7a73d) -30%, var(--caf-nav-2) 60%);
}

.caf-mosaic-mark {
  font-size: 26px;
  font-weight: 800;
  color: #ffffff;
  letter-spacing: 1.4px;
}

/* ── Loading behaviour ─────────────────────────────────────────────────────
   A thumbnail that is still arriving shows a quiet shimmer, not a fallback
   glyph that reads as "there is no image here". The semantic fallback is for
   media that genuinely has none, or an image that genuinely failed. */

.caf-thumb-img,
.caf-avatar-img {
  opacity: 0;
  transition: opacity 0.22s ease;
}

.caf-thumb-img.is-loaded,
.caf-avatar-img.is-loaded { opacity: 1; }

.caf-thumb-fallback::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, transparent 20%, rgba(255, 255, 255, 0.07) 42%, transparent 64%);
  background-size: 260% 100%;
  animation: caf-shimmer 1.5s ease-in-out infinite;
}

/* Once the real image is in, or once it has failed, the shimmer stops. */
.caf-thumb.has-image .caf-thumb-fallback::after,
.caf-thumb.img-failed .caf-thumb-fallback::after { content: none; }

.caf-thumb.has-image .caf-thumb-glyph { opacity: 0; }

@keyframes caf-shimmer {
  from { background-position: 130% 0; }
  to { background-position: -30% 0; }
}

@media (prefers-reduced-motion: reduce) {
  .caf-thumb-fallback::after { animation: none; }
}

/* Present for assistive technology, absent visually — used where a design
   device carries the meaning on screen but must not lose it for a reader. */
.caf-visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Form text reads left, inside CAFlirary only ──────────────────────────
   style.css centres every text input and select platform-wide:

     input:not([type=checkbox]):not([type=radio]):not([type=file]), select
       { text-align: center; text-align-last: center }

   That rule is shared with Kora, CAFnizer, CAFguard, Nexus and the rest, so it
   is deliberately left alone. Inside CAFlirary it made a clip title, a law
   selection, a timecode and a search box all render centred, which reads as a
   dialog box rather than a working document. The override is scoped to the
   CAFlirary body class and beats the global rule on specificity alone —
   no !important, so a component can still opt back into centring. */
body.caflirary-page input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not(.mto-code-input),
body.caflirary-page select,
body.caflirary-page textarea {
  text-align: left;
  text-align-last: auto;
}

/* The same global block also sets the input colour to rgba(5,32,15,.82) — a
   near-black green written for the light theme. On CAFlirary's navy surfaces
   that made typed text almost invisible: a search for "Offside" looked like an
   empty box. The caret goes with it, so the cursor was invisible too. */
body.caflirary-page input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
body.caflirary-page select,
body.caflirary-page textarea {
  color: var(--caf-text-primary, #f2f7fb);
  caret-color: var(--caf-gold, #d7a73d);
}

body.caflirary-page input::placeholder,
body.caflirary-page textarea::placeholder {
  color: #7a8ea3;
}

/* Timecodes are read as numbers, not prose: centring them is the deliberate
   choice the Clip Studio already makes for its readout boxes. */
body.caflirary-page input.caf-clip-input[inputmode="numeric"] {
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* A band-only competition treatment: the category cue and season, with no
   wordmark, for cards small enough that the name is printed beside them. */
.caf-artwork.is-bandonly { aspect-ratio: 16 / 6; }

.caf-artwork-category {
  position: absolute;
  left: 15px;
  bottom: 11px;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.88);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}
