/* ===== The artwork board — 1080 x 1350 (Instagram 4:5), or 1080 x 1920 story =====

   Every value is in artwork pixels; the preview scales the whole board with a
   transform, so nothing here may depend on the viewport.

   Look follows the Craftfiti BKK design system (Oct 2026, the CraftfitiWeb
   CI — "Craftfiti BKK brand identity moodboard/design-system"): a flyer pinned
   to the bar wall. Paper or night ground, ink outlines instead of soft shadows,
   yellow as the paint can (never as text on paper), red as the marker pen,
   Playfair Display 900 for titles, Poppins for everything set, Permanent
   Marker only for stickers and hand notes. Anything stuck on is tilted.
   The July gold / Cormorant look is retired.

   html2canvas renders these rules literally. Plain boxes, flex, grid, gradients,
   inline SVG and filters on <img> are safe; backdrop-filter and CSS masks are not.
   NO box-shadow on anything rotated: html2canvas draws the shadow unrotated and
   off to one side (black slabs on the PNG). The sticker's hard shadow is a
   thicker right/bottom ink border instead. */

#artwork {
  --ink: #15110d; --ink-2: #1e1812; --ink-4: #2a221a;
  --paper: #ede8dd; --cream: #f6f2ea;
  --yellow: #f5d547; --red: #a3232b; --hilite: #f1e2a0;
  --tape: rgba(241, 226, 160, .85);
  --muted: #cfc6b6; --line: #3a3128; --label: #5a5146;
  --display: 'Playfair Display', Georgia, serif;
  --sans: Poppins, Prompt, sans-serif;
  --marker: 'Permanent Marker', cursive;

  width: 1080px; height: 1350px; box-sizing: border-box;
  transform-origin: top left; position: absolute; top: 0; left: 0;
  padding: 46px; display: flex; flex-direction: column; overflow: hidden;
  font-family: var(--sans);
  color: var(--ink);
  background-color: var(--paper);
  /* paper with a little tooth: a soft light patch and a fine diagonal grain */
  background-image:
    radial-gradient(circle at 18% 6%, rgba(246, 242, 234, .9) 0%, rgba(246, 242, 234, 0) 55%),
    repeating-linear-gradient(115deg, rgba(21, 17, 13, .022) 0 1px, rgba(21, 17, 13, 0) 1px 7px),
    linear-gradient(165deg, #f1ece2 0%, #ede8dd 50%, #e3dccd 100%);
}
#artwork.dark {
  color: var(--cream);
  background-color: var(--ink);
  background-image:
    radial-gradient(circle at 50% 16%, #2a221a 0%, rgba(42, 34, 26, 0) 58%),
    repeating-linear-gradient(115deg, rgba(246, 242, 234, .018) 0 1px, rgba(246, 242, 234, 0) 1px 7px),
    linear-gradient(170deg, #1e1812 0%, #15110d 55%, #0e0b08 100%);
}

/* Story (9:16): the 4:5 post sits in the middle band, which is exactly the part
   Instagram leaves uncovered (profile row on top, reply bar at the bottom).
   285 + 46 top and bottom leaves the same 1258px content box as the post, so
   every template lays out identically in both sizes. */
#artwork.story { height: 1920px; padding: 331px 46px; }

.art-frame {
  position: absolute; top: 24px; left: 24px; right: 24px; bottom: 24px;
  border: 3px solid var(--ink); border-radius: 2px; pointer-events: none;
}
#artwork.dark .art-frame { border: 2px solid rgba(246, 242, 234, .85); }
/* the story bands are part of the wall: the frame holds the post, a strip of
   tape holds the frame */
#artwork.story .art-frame { top: 309px; bottom: 309px; }
.art-tape { display: none; }
#artwork.story .art-tape { display: block; position: absolute; width: 190px; height: 44px;
  background: var(--tape); pointer-events: none; z-index: 1; }
#artwork.story .art-tape.t1 { top: 288px; left: 120px; transform: rotate(-4deg); }
#artwork.story .art-tape.t2 { bottom: 288px; right: 120px; transform: rotate(3deg); }

/* marker-xl watermark on night grounds */
.art-watermark { position: absolute; right: 60px; bottom: 150px; font-family: var(--marker);
  font-size: 190px; letter-spacing: 6px; color: var(--cream); opacity: .045;
  transform: rotate(-8deg); pointer-events: none; white-space: nowrap; }
#artwork.story .art-watermark { bottom: 440px; }

/* ---- masthead ---- */
.art-head { height: 70px; flex: 0 0 auto; display: flex; align-items: center;
  justify-content: space-between; position: relative; z-index: 1; }
.brand { display: flex; align-items: flex-end; gap: 11px; }
.brand .wordmark { height: 62px; width: auto; display: block; }
.brand img { height: 60px; width: auto; object-fit: contain; }

.pl-lockup { display: flex; align-items: center; gap: 12px; }
.pl-lockup img { height: 44px; width: auto; object-fit: contain; }
/* an ink pill with a yellow label — cf-btn--pill */
.pl-text { font-family: var(--sans); font-size: 15px; font-weight: 700; letter-spacing: 2.5px;
  text-transform: uppercase; background: var(--ink); color: var(--yellow);
  border-radius: 999px; padding: 11px 22px 10px; line-height: 1; }
#artwork.dark .pl-text { background: var(--yellow); color: var(--ink); }
.pl-ring { display: none; }
.pl-lockup.has-logo .pl-text { display: none; }

/* ---- fixtures ---- */
.art-fixtures { flex: 0 0 auto; display: grid; gap: 0; }
.art-fixtures.cols-1 { grid-template-columns: minmax(0, 1fr); }
.art-fixtures.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.art-fixtures.cols-2 .fx:first-child { border-right: 2px dashed rgba(21, 17, 13, .35); }

.fx { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; }
/* kick-off time is a yellow sticker slapped on: marker, hard ink shadow, tilted */
.fx-time { font-family: var(--marker); font-size: 30px; line-height: 1.1; color: var(--ink);
  background: var(--yellow); padding: 6px 18px 4px; transform: rotate(-4deg); white-space: nowrap;
  border-right: 4px solid var(--ink); border-bottom: 4px solid var(--ink); }
#artwork.dark .fx-time { border-color: var(--cream); }
.fx-teams { display: flex; align-items: center; gap: 18px; }
.fx-side { display: flex; flex-direction: column; align-items: center; gap: 12px; width: 168px; }
.fx-badge { width: 104px; height: 104px; border-radius: 50%; background: var(--cream);
  border: 3px solid var(--ink); box-sizing: border-box; padding: 12px;
  display: flex; align-items: center; justify-content: center; overflow: hidden; flex: 0 0 auto;
  font-family: var(--sans); font-weight: 800; font-size: 20px; letter-spacing: 1px; color: var(--line); }
#artwork.dark .fx-badge { background: var(--cream); border-color: var(--cream); }
.fx-badge img { width: 100%; height: 100%; object-fit: contain; }
.fx-name { font-family: var(--sans); font-weight: 700; font-size: 21px;
  letter-spacing: 2px; text-align: center; line-height: 1.15; text-transform: uppercase; }
.fx-vs { font-family: var(--display); font-style: italic; font-weight: 900; font-size: 34px;
  color: var(--red); flex: 0 0 auto; }
#artwork.dark .fx-vs { color: var(--yellow); }

/* big match: names beside the badges, set large */
.tpl-bigmatch .fx-teams { gap: 26px; width: 100%; justify-content: center; }
.tpl-bigmatch .fx-side { flex-direction: row; align-items: center; width: auto; gap: 20px; flex-grow: 1; }
.tpl-bigmatch .fx-side.left { justify-content: flex-end; }
.tpl-bigmatch .fx-side.right { flex-direction: row-reverse; justify-content: flex-end; }
.tpl-bigmatch .fx-badge { width: 110px; height: 110px; }
.tpl-bigmatch .fx-name { font-family: var(--display); font-weight: 900; font-size: 56px;
  letter-spacing: 1px; }
.tpl-bigmatch .fx-vs { font-size: 40px; }

/* ---- player strip ----
   Panels are tiles: 2.5px ink outline, 16px radius, the club badge pressed
   faintly into the ground BEHIND the cut-out. */
.art-photos { flex: 0 0 auto; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }

/* Two pairs with a channel between them, so the strip reads as two fixtures
   rather than four players in one match. The channel lines up with the rule
   that divides the two fixtures in the header above. */
.art-photos.paired { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 38px; }
.photo-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.slot-box { position: relative; overflow: hidden; box-sizing: border-box;
  border: 3px solid var(--ink); border-radius: 16px;
  background-color: var(--cream);
  background-image:
    repeating-linear-gradient(115deg, rgba(21, 17, 13, .03) 0 1px, rgba(21, 17, 13, 0) 1px 9px),
    linear-gradient(180deg, #f6f2ea 0%, #ece5d6 60%, #ddd3bf 100%);
  display: flex; align-items: flex-end; justify-content: center; }
/* Every panel on a post shares one ground — paper templates cream, night
   templates ink. A yellow/ink or cream/ink split read as "this side is
   different" with nothing on the post saying why (Singh, 24 Oct); the faint
   club badge behind each player is what tells the sides apart. */

/* Faint enough to be felt rather than seen. */
.slot-wash { position: absolute; top: 10%; left: 50%; width: 104%; transform: translateX(-50%);
  opacity: .16; pointer-events: none; }
/* The image is already a toned, edge-faded silhouette (badgeWash in app.js). */
.slot-wash img { width: 100%; height: auto; display: block; }
/* PHOTO BOX — the player photo is positioned and sized by applyFrame() in
   app.js, in pixels. object-fit is deliberately not used: html2canvas, which
   writes the downloaded PNG, does not implement it and stretched every photo
   to fill its panel, so the export did not match the preview. */
.slot-box img { position: absolute; display: block; max-width: none; }
.slot-box.tone-mono img { filter: grayscale(1) contrast(1.04); }
.slot-box.tone-sepia img { filter: grayscale(1) sepia(.55) saturate(1.6) contrast(1.05); }
.slot-box.tone-ink img { filter: grayscale(1) contrast(1.2) brightness(.86); }
/* The caption sits over the photo; let drags pass through to it. */
.slot-cap, .camp-cap, .duel-cap, .camp-tag, .duel-club, .slot-wash { pointer-events: none; }
.slot-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 30px 12px 14px;
  background: linear-gradient(180deg, rgba(21, 17, 13, 0) 0%, rgba(21, 17, 13, .86) 58%); }
.slot-cap .n { font-family: var(--sans); font-weight: 800; font-size: 22px;
  letter-spacing: 1px; color: var(--cream); line-height: 1.1; }
.slot-cap .t { font-family: var(--sans); font-weight: 700; font-size: 12px; letter-spacing: 2px;
  text-transform: uppercase; color: var(--yellow); margin-top: 4px; }
.slot-ghost { display: block; }

/* big match: two camps on the same ink ground */
.tpl-bigmatch .art-photos { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.camp { position: relative; overflow: hidden; display: grid; box-sizing: border-box;
  grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0;
  border: 3px solid var(--cream); border-radius: 16px; }
.camp { background-color: var(--ink-4);
  background-image:
    repeating-linear-gradient(115deg, rgba(246, 242, 234, .035) 0 1px, rgba(246, 242, 234, 0) 1px 9px),
    linear-gradient(180deg, #3a3128 0%, #2a221a 60%, #1e1812 100%); }
.camp-half { position: relative; display: flex; align-items: flex-end; justify-content: center;
  overflow: hidden; }
.camp .slot-wash { opacity: .2; }
.camp .camp-half:first-child { border-right: 2px solid rgba(246, 242, 234, .12); }
.camp-half img { position: absolute; display: block; max-width: none; }
.camp-tag { position: absolute; top: 18px; z-index: 2; font-family: var(--sans); font-weight: 800;
  font-size: 14px; letter-spacing: 3px; text-transform: uppercase; padding: 6px 14px 5px;
  border-radius: 999px; }
.camp-tag { background: var(--yellow); color: var(--ink); }
.camp.home .camp-tag { left: 18px; }
.camp.away .camp-tag { right: 18px; }
.camp-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 34px 14px 16px; display: flex; }
.camp-cap { background: linear-gradient(180deg, rgba(21, 17, 13, 0) 0%, rgba(21, 17, 13, .88) 60%); }
.camp-cap div { flex: 1 1 0; text-align: center; font-family: var(--sans);
  font-weight: 800; font-size: 22px; letter-spacing: 1px; color: var(--cream); }

/* ---- key battle: two cream sides, a yellow seam, a stamped VS ---- */
.art-duel { flex: 1 1 auto; display: grid; grid-template-columns: 1fr 8px 1fr;
  min-height: 0; position: relative; border: 3px solid var(--ink); border-radius: 16px;
  overflow: hidden; }
.duel-seam { background: var(--yellow); border-left: 3px solid var(--ink); border-right: 3px solid var(--ink); }
.duel-vs {
  position: absolute; top: 50%; left: 50%; width: 138px; height: 138px;
  margin: -69px 0 0 -69px; border-radius: 50%; box-sizing: border-box;
  background: var(--yellow); border: 5px solid var(--ink); border-width: 5px 10px 10px 5px;
  display: flex; align-items: center; justify-content: center; z-index: 2;
  font-family: var(--display); font-weight: 900; font-size: 54px;
  letter-spacing: 1px; color: var(--ink); transform: rotate(-10deg);
}
.duel-side { position: relative; overflow: hidden; display: flex; align-items: flex-end;
  justify-content: center; }
.duel-side.a { background-color: var(--cream);
  background-image:
    repeating-linear-gradient(115deg, rgba(21, 17, 13, .03) 0 1px, rgba(21, 17, 13, 0) 1px 9px),
    linear-gradient(180deg, #f6f2ea 0%, #ece5d6 60%, #ddd3bf 100%); }
.duel-side.b { background-color: var(--cream);
  background-image:
    repeating-linear-gradient(115deg, rgba(21, 17, 13, .03) 0 1px, rgba(21, 17, 13, 0) 1px 9px),
    linear-gradient(180deg, #f6f2ea 0%, #ece5d6 60%, #ddd3bf 100%); }
.duel-side .slot-wash { top: 12%; width: 92%; opacity: .16; }
.duel-side img { position: absolute; display: block; max-width: none; }
.duel-club { position: absolute; top: 22px; z-index: 1; font-family: var(--sans); font-weight: 800;
  font-size: 14px; letter-spacing: 3px; text-transform: uppercase; padding: 7px 15px 6px;
  border-radius: 999px; }
.duel-side.a .duel-club { left: 22px; background: var(--ink); color: var(--yellow); }
.duel-side.b .duel-club { right: 22px; background: var(--ink); color: var(--yellow); }
.duel-cap { position: absolute; left: 0; right: 0; bottom: 0; padding: 40px 26px 26px;
  background: linear-gradient(180deg, rgba(21, 17, 13, 0) 0%, rgba(21, 17, 13, .88) 58%); }
.duel-side.b .duel-cap { text-align: right; }
.duel-cap .n { font-family: var(--display); font-weight: 900; font-size: 46px;
  letter-spacing: .5px; color: var(--cream); line-height: 1.05; }
.duel-cap .s { font-family: var(--sans); font-weight: 700; font-size: 15px; letter-spacing: 2px;
  text-transform: uppercase; color: var(--yellow); margin-top: 10px; }

/* ---- beer mat: a cream coaster with an ink rim, held on by tape. The mat
   itself sits straight — tilted it read as a mistake (Singh, 24 Oct); the tape
   and the red kicker carry the stuck-on feel. ---- */
.art-coaster { width: 840px; height: 840px; flex: 0 0 auto; align-self: center; box-sizing: border-box;
  border-radius: 50%; border: 5px solid var(--ink);
  background: var(--cream);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  position: relative; }
.art-coaster .inner-ring { position: absolute; top: 22px; left: 22px; right: 22px; bottom: 22px;
  border-radius: 50%; border: 2px dashed rgba(21, 17, 13, .35); }
.art-coaster .coaster-tape { position: absolute; top: -18px; left: 50%; width: 200px; height: 46px;
  margin-left: -100px; background: var(--tape); transform: rotate(-6deg); }
.coaster-kicker { font-family: var(--sans); font-weight: 800; font-size: 16px; letter-spacing: 5px;
  text-transform: uppercase; color: var(--cream); background: var(--red);
  padding: 7px 18px 6px; transform: rotate(-3deg); text-indent: 5px; }
.coaster-badges { display: flex; align-items: center; gap: 36px; margin-top: 40px; }
.coaster-badges .fx-badge { width: 158px; height: 158px; padding: 18px; font-size: 30px; }
.coaster-vs { font-family: var(--marker); font-size: 54px; color: var(--red);
  transform: rotate(-8deg); }
.coaster-teams { font-family: var(--display); font-weight: 900; font-size: 66px;
  letter-spacing: 1px; line-height: 1.08; text-align: center; margin-top: 34px;
  text-transform: uppercase; }
.coaster-when { display: flex; align-items: center; gap: 16px; margin-top: 30px; }
.coaster-when .rule { width: 62px; height: 3px; background: var(--ink); }
.coaster-when .txt { font-family: var(--sans); font-weight: 700; font-size: 22px; letter-spacing: 3px;
  text-transform: uppercase; }

/* ---- rows: results, schedule, triple header ---- */
.art-rows { flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center;
  min-height: 0; }
.tpl-weekend .art-rows, .tpl-triple .art-rows { justify-content: flex-start; }
.row-line { flex: 1 1 0; max-height: 118px; display: flex; align-items: center; gap: 24px;
  padding: 0 6px; border-top: 2px solid var(--ink); }
#artwork.dark .row-line { border-top-color: rgba(246, 242, 234, .3); }
.row-line:last-child { border-bottom: 2px solid var(--ink); }
#artwork.dark .row-line:last-child { border-bottom-color: rgba(246, 242, 234, .3); }
.row-side { flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 16px; }
.row-side.left { justify-content: flex-end; }
.row-badge { width: 66px; height: 66px; border-radius: 50%; flex: 0 0 auto; overflow: hidden;
  box-sizing: border-box; padding: 8px; background: var(--cream); border: 2.5px solid var(--ink); }
#artwork.dark .row-badge { border-color: var(--cream); }
.row-badge img { width: 100%; height: 100%; object-fit: contain; }
/* One line always: a long club name is shrunk to fit by fitOneLine() in app.js
   rather than wrapping, which would push its badge out of the column. */
.row-team { font-family: var(--sans); font-weight: 800; font-size: 32px;
  letter-spacing: 1.5px; text-transform: uppercase; line-height: 1.15; min-width: 0;
  white-space: nowrap; overflow: hidden; }
.row-side.left .row-team { text-align: right; }
.row-side.right .row-team { text-align: left; }
.row-team.dim { color: #8a8173; }
/* Fixed width, or a 1-goal scoreline and a 2-goal one shift the badges apart. */
.row-score { flex: 0 0 180px; display: flex; align-items: center; justify-content: center;
  gap: 14px; font-family: var(--display); font-weight: 900; font-size: 54px; line-height: 1; }
.row-score .win { color: var(--yellow); }
.row-score .lose, .row-score .dash { color: #8a8173; }
.row-score .dash { font-size: 30px; }
.row-vs { flex: 0 0 auto; font-family: var(--display); font-style: italic; font-weight: 900;
  font-size: 24px; color: var(--red); }
#artwork.dark .row-vs { color: var(--yellow); }
.row-time { flex: 0 0 96px; font-family: var(--marker); font-size: 26px; color: var(--red); }
#artwork.dark .row-time { color: var(--yellow); }

/* day header = a highlighter band, like an event night on the calendar */
.day-head { flex: 0 0 auto; display: flex; align-items: center; gap: 14px; padding: 12px 0 8px; }
.day-head .d { font-family: var(--sans); font-weight: 800; font-size: 22px; letter-spacing: 3px;
  text-transform: uppercase; background: var(--hilite); color: var(--ink); padding: 6px 14px 5px; }
.day-head .rule { flex-grow: 1; height: 3px; background: var(--ink); }

/* schedule rows sit tighter than results rows */
.tpl-weekend .row-line { gap: 18px; padding: 0 4px; border-top-width: 1.5px; }
.tpl-weekend .row-line:last-child { border-bottom-width: 1.5px; }
.tpl-weekend .row-side, .tpl-lineup .row-side { gap: 12px; }
.tpl-weekend .row-badge, .tpl-lineup .row-badge { width: 48px; height: 48px; padding: 5px; border-width: 2px; }
.tpl-weekend .row-team, .tpl-lineup .row-team { font-size: 26px; letter-spacing: 1.5px; }

/* triple header gives each fixture a full block */
.tpl-triple .row-line { flex-direction: column; align-items: stretch; justify-content: center;
  gap: 16px; max-height: none; padding: 0 8px; }
.tpl-triple .row-when { display: flex; align-items: center; gap: 16px; }
.tpl-triple .row-when .lbl { font-family: var(--sans); font-weight: 700; font-size: 14px;
  letter-spacing: 3px; text-transform: uppercase; color: var(--label); }
.tpl-triple .row-time { flex: 0 0 auto; font-size: 30px; color: var(--ink); background: var(--yellow);
  padding: 4px 16px 2px; transform: rotate(-3deg);
  border-right: 4px solid var(--ink); border-bottom: 4px solid var(--ink); }
.tpl-triple .row-pair { display: flex; align-items: center; gap: 22px; }
.tpl-triple .row-badge { width: 78px; height: 78px; }
.tpl-triple .row-team { font-size: 38px; }
.tpl-triple .row-vs { font-size: 30px; }

/* ---- headline block above a list ---- */
.art-topline { flex: 0 0 auto; display: flex; align-items: flex-end; justify-content: space-between;
  border-bottom: 4px solid var(--ink); padding-bottom: 16px; }
.art-topline .lead { flex: 1 1 auto; min-width: 0; }
.art-topline .kick { font-family: var(--sans); font-weight: 700; font-size: 15px; letter-spacing: 4px;
  text-transform: uppercase; color: var(--red); }
.art-topline .big { font-family: var(--display); font-weight: 900; font-size: 98px;
  letter-spacing: 1px; line-height: 1; margin-top: 8px; white-space: nowrap; text-transform: uppercase; }
.art-topline .side { flex: 0 0 auto; margin-left: 20px; margin-bottom: 12px;
  font-family: var(--marker); font-size: 30px; color: var(--ink); background: var(--yellow);
  padding: 6px 18px 4px; transform: rotate(-7deg);
  border-right: 4px solid var(--ink); border-bottom: 4px solid var(--ink); }

/* ---- centred title stack ---- */
/* Centred in whatever height it is given. */
.art-title { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center;
  justify-content: center; }
.title-kicker { font-family: var(--sans); font-weight: 700; font-size: 17px; letter-spacing: 6px;
  text-transform: uppercase; color: var(--red); text-indent: 6px; }
#artwork.dark .title-kicker { color: var(--muted); }
.title-big { font-family: var(--display); font-weight: 900; letter-spacing: 1px;
  line-height: 1; margin-top: 10px; font-size: 100px; text-transform: uppercase;
  text-align: center; }
#artwork.dark .title-big { color: var(--cream); }
.title-rule { display: flex; align-items: center; justify-content: center; margin-top: 12px; }
.title-rule svg { display: block; }
.title-hand { font-family: var(--marker); font-size: 40px; color: var(--red);
  transform: rotate(-3deg); margin-top: 16px; }
#artwork.dark .title-hand { color: var(--yellow); }
/* the house line as an ink pill with a yellow label */
.title-note { font-family: var(--sans); font-weight: 700; font-size: 16px; letter-spacing: 3px;
  text-transform: uppercase; color: var(--yellow); background: var(--ink); border-radius: 999px;
  padding: 12px 26px 11px; margin-top: 22px; text-align: center; line-height: 1.2; }
#artwork.dark .title-note { color: var(--ink); background: var(--yellow); }

/* ---- one-line footer ---- */
.art-footline { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.art-footline .hand { font-family: var(--marker); font-size: 32px; color: var(--red);
  transform: rotate(-3deg); }
#artwork.dark .art-footline .hand { color: var(--yellow); }
.art-footline .note { font-family: var(--sans); font-weight: 700; font-size: 15px; letter-spacing: 3px;
  text-transform: uppercase; color: var(--line); }
#artwork.dark .art-footline .note { color: var(--muted); }
.art-footline .mark { font-family: var(--sans); font-weight: 800; font-size: 16px; letter-spacing: 3px;
  background: var(--ink); color: var(--yellow); border-radius: 999px; padding: 10px 20px 9px; }
#artwork.dark .art-footline .mark { background: var(--yellow); color: var(--ink); }

.gap { flex: 0 0 auto; }

/* ---- derby: night ground, the rivalry's name stamped huge ---- */
.tpl-derby .title-kicker { font-family: var(--display); font-weight: 900; font-size: 74px;
  letter-spacing: 1px; color: var(--cream); text-indent: 0; line-height: 1; white-space: nowrap; }
.tpl-derby .title-big { color: var(--yellow); font-size: 190px; line-height: .9; margin-top: 4px;
  letter-spacing: 4px; }
#artwork.tpl-derby .title-big { color: var(--yellow); }
.derby-league { font-family: var(--sans); font-weight: 700; font-size: 15px; letter-spacing: 5px;
  text-transform: uppercase; color: var(--muted); margin-bottom: 14px; text-indent: 5px; }
.art-derby { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: 1fr 1fr;
  gap: 18px; position: relative; }
.derby-side { position: relative; overflow: hidden; box-sizing: border-box; border-radius: 16px;
  border: 3px solid var(--cream); display: flex; align-items: flex-end; justify-content: center; }
.derby-side { background-color: var(--ink-4);
  background-image:
    repeating-linear-gradient(115deg, rgba(246, 242, 234, .035) 0 1px, rgba(246, 242, 234, 0) 1px 9px),
    linear-gradient(180deg, #3a3128 0%, #2a221a 60%, #1e1812 100%); }
.derby-side .slot-wash { top: 8%; width: 96%; opacity: .2; }
.derby-side img { position: absolute; display: block; max-width: none; transform-origin: center center; }
.derby-side .duel-cap .n { font-size: 40px; }
.derby-side.b .duel-cap { text-align: right; }
.derby-side .duel-club { top: 20px; }
.derby-side.a .duel-club { left: 20px; background: var(--yellow); color: var(--ink); }
.derby-side.b .duel-club { right: 20px; background: var(--yellow); color: var(--ink); }
.art-derby .duel-vs { border-right-color: var(--cream); border-bottom-color: var(--cream); }
.derby-strip { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  gap: 18px; }
.derby-strip .row-side { gap: 16px; }
.derby-strip .row-team { font-size: 30px; color: var(--cream); }
.derby-strip .row-badge { width: 74px; height: 74px; border-color: var(--cream); }
.derby-strip .fx-time { flex: 0 0 auto; }
.derby-foot { flex: 0 0 auto; display: flex; align-items: center; justify-content: space-between;
  gap: 20px; }
.derby-foot .title-hand { margin-top: 0; font-size: 34px; }
.derby-foot .title-note { margin-top: 0; }

/* ---- free object layer: text and images placed by hand ---- */
/* The layer spans the whole board, so it has to be transparent to the pointer —
   otherwise it swallows every click and drag meant for the photos underneath.
   The objects themselves take pointer events back. */
#art-objects { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.aobj {
  position: absolute; cursor: move; touch-action: none; pointer-events: auto;
  line-height: 1.16; word-wrap: break-word;
  /* Typed line breaks are kept as typed — the text box is a multi-line field. */
  white-space: pre-wrap;
  transform-origin: center center;   /* tilt turns about the middle, not a corner */
}
.aobj.image { overflow: hidden; }
.aobj.image img { width: 100%; height: 100%; object-fit: contain; display: block;
  pointer-events: none; }
.aobj-handle { display: none; }

/* Selection chrome exists only while editing — the export removes .editing so
   none of it lands in the PNG.

   --hk / --hoff / --ow are written by ArtObjects.chrome() in BOARD pixels that
   come out to a constant size on the glass. Hard-coded pixels here would be
   divided by the preview scale (≈3 on a phone) and become untouchable. */
#artwork.editing .aobj.sel { outline: var(--ow, 2px) solid #f5d547; outline-offset: 3px; }
#artwork.editing .aobj.sel .aobj-handle {
  display: block; position: absolute;
  width: var(--hk, 34px); height: var(--hk, 34px); border-radius: 50%;
  background: #f5d547; border: var(--ow, 3px) solid #15110d;
  touch-action: none;
}
#artwork.editing .aobj.sel .aobj-handle.resize {
  right: calc(0px - var(--hoff, 17px)); bottom: calc(0px - var(--hoff, 17px));
  cursor: nwse-resize;
}
/* Tilt handle sits above the box so it never overlaps the resize one. */
#artwork.editing .aobj.sel .aobj-handle.rotate {
  left: 50%; top: calc(0px - var(--hk, 34px) * 1.4);
  margin-left: calc(0px - var(--hoff, 17px));
  background: #f6f2ea; border-color: #15110d; cursor: grab;
}

/* ---- moving the template's own text ----
   Normally these blocks are laid out by the template and take no pointer
   events at all. "ย้ายข้อความเดิม" turns them into drag targets: the whole
   block is the target, which is the only size that works under a thumb. */
#artwork.nudging .nudgeable {
  pointer-events: auto !important; cursor: move; touch-action: none;
  outline: var(--ow, 2px) dashed rgba(163, 35, 43, .8); outline-offset: 2px;
}
#artwork.dark.nudging .nudgeable { outline-color: rgba(245, 213, 71, .85); }
#artwork.nudging .nudgeable.moved { outline-style: solid; }
#artwork.nudging .slot-box img, #artwork.nudging .camp-half img,
#artwork.nudging .duel-side img, #artwork.nudging .derby-side img,
#artwork.nudging .hero-stage img, #artwork.nudging .split-side img { pointer-events: none; }

/* ---- per-slot photo framing ----
   object-position pans the photo inside its slot; scale zooms it. Both are
   set inline from the slot's own numbers. */
.slot-box img, .camp-half img, .duel-side img { transform-origin: center center; }

/* ===== Oct 2026 — six more templates ===== */

/* ---- TICKET: a portrait admission ticket with a tear-off stub ---- */
.art-ticket { width: 760px; flex: 1 1 auto; min-height: 0; align-self: center; position: relative;
  display: flex; flex-direction: column; box-sizing: border-box;
  border: 4px solid var(--ink); border-radius: 22px;
  background-color: var(--cream);
  background-image:
    repeating-linear-gradient(115deg, rgba(21, 17, 13, .03) 0 1px, rgba(21, 17, 13, 0) 1px 9px),
    linear-gradient(180deg, #f6f2ea 0%, #ece5d6 60%, #ddd3bf 100%); }
.ticket-tape { position: absolute; top: -22px; left: 50%; width: 200px; height: 46px;
  margin-left: -100px; background: var(--tape); transform: rotate(-5deg); z-index: 2; }
.ticket-main { flex: 1 1 auto; min-height: 0; padding: 44px 40px; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
.ticket-league { font-family: var(--sans); font-weight: 700; font-size: 15px; letter-spacing: 5px;
  text-transform: uppercase; color: var(--red); text-indent: 5px; }
.ticket-kicker { font-family: var(--display); font-weight: 900; font-size: 86px; line-height: 1.05;
  text-transform: uppercase; margin-top: 10px; }
.ticket-main .coaster-badges { margin-top: 34px; gap: 36px; }
.ticket-main .coaster-badges .fx-badge { width: 150px; height: 150px; padding: 17px; font-size: 28px; }
.ticket-teams { margin-top: 26px; }
.ticket-teams div { width: 640px; max-width: 100%; font-family: var(--display); font-weight: 900;
  font-size: 58px; line-height: 1.1; text-transform: uppercase; text-align: center;
  white-space: nowrap; overflow: hidden; min-width: 0; }
.ticket-when { font-family: var(--marker); font-size: 32px; line-height: 1.1; color: var(--ink);
  background: var(--yellow); padding: 6px 18px 4px; transform: rotate(-3deg); white-space: nowrap;
  border-right: 4px solid var(--ink); border-bottom: 4px solid var(--ink); margin-top: 30px; }
.ticket-note { margin-top: 26px; }
/* the perforation: a dashed rule with a half-moon bitten out of each edge */
.ticket-tear { flex: 0 0 auto; height: 0; border-top: 3px dashed var(--ink); margin: 0 26px;
  position: relative; }
.ticket-tear .notch { position: absolute; top: -24px; width: 22px; height: 44px; box-sizing: border-box;
  background: var(--paper); border: 4px solid var(--ink); }
.ticket-tear .notch.l { left: -30px; border-left: 0; border-radius: 0 22px 22px 0; }
.ticket-tear .notch.r { right: -30px; border-right: 0; border-radius: 22px 0 0 22px; }
.ticket-stub { flex: 0 0 170px; padding: 22px 40px; box-sizing: border-box; display: flex;
  flex-direction: row; justify-content: space-between; align-items: center; }
.stub-lbl { font-family: var(--sans); font-weight: 700; font-size: 13px; letter-spacing: 4px;
  text-transform: uppercase; color: var(--label); }
.stub-val { font-family: var(--marker); font-size: 34px; color: var(--red); margin-top: 4px; white-space: nowrap; }
.stub-code { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.barcode { width: 190px; height: 96px; }
.barcode svg { display: block; }
.stub-no { font-family: var(--sans); font-weight: 700; font-size: 13px; letter-spacing: 3px; }

/* ---- CHALKBOARD: marker lettering on a blackboard in a wooden frame ---- */
.tpl-chalk .art-watermark { display: none; }
.art-chalk { flex: 1 1 auto; min-height: 0; position: relative; display: flex; flex-direction: column;
  padding: 40px 44px; box-sizing: border-box; border: 14px solid #5a4634; border-radius: 6px;
  background-color: #1b2320;
  background-image: radial-gradient(circle at 70% 85%, rgba(246, 242, 234, .07), transparent 55%); }
.chalk-inner { position: absolute; top: 10px; left: 10px; right: 10px; bottom: 10px;
  border: 2px dashed rgba(246, 242, 234, .35); pointer-events: none; }
.chalk-title { flex: 0 0 auto; font-family: var(--marker); font-size: 92px; line-height: 1; color: var(--cream);
  transform: rotate(-2deg); text-align: center; white-space: nowrap; }
.art-chalk .title-rule { flex: 0 0 auto; }
.chalk-rows { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; justify-content: center; }
.chalk-row { flex: 1 1 0; max-height: 200px; display: flex; align-items: center; gap: 22px; }
.chalk-row + .chalk-row { border-top: 2px dashed rgba(246, 242, 234, .22); }
.chalk-time { flex: 0 0 150px; font-family: var(--marker); font-size: 40px; color: var(--yellow); }
.chalk-team { min-width: 0; font-family: var(--marker); font-size: 52px; line-height: 1.15; color: var(--cream);
  white-space: nowrap; overflow: hidden; }
.chalk-row .row-side.left .chalk-team { text-align: right; }
.chalk-row .row-side.right .chalk-team { text-align: left; }
.tpl-chalk .row-badge { width: 64px; height: 64px; border-color: var(--cream); }
.chalk-vs { flex: 0 0 auto; font-family: var(--marker); font-size: 34px; color: var(--red);
  transform: rotate(-8deg); }
.chalk-foot { flex: 0 0 auto; display: flex; flex-direction: row; justify-content: space-between;
  align-items: center; gap: 20px; }
.chalk-note { flex: 1 1 auto; min-width: 0; font-family: var(--marker); font-size: 26px; line-height: 1.1;
  color: var(--yellow); }
.chalk-doodle { flex: 0 0 auto; font-family: var(--marker); font-size: 46px; color: var(--cream);
  transform: rotate(6deg); white-space: nowrap; }

/* ---- FRONT PAGE: a broadsheet ---- */
.news-mast { flex: 0 0 auto; text-align: center; border-top: 6px double var(--ink);
  border-bottom: 2px solid var(--ink); padding: 14px 0 10px; }
.news-name { font-family: var(--display); font-weight: 900; font-size: 84px; text-transform: uppercase;
  letter-spacing: 2px; line-height: 1; white-space: nowrap; overflow: hidden; }
.news-dateline { display: flex; flex-direction: row; justify-content: space-between; margin-top: 10px;
  font-family: var(--sans); font-weight: 700; font-size: 14px; letter-spacing: 4px; text-transform: uppercase; }
.news-lead { flex: 0 0 auto; text-align: center; }
.news-tag { display: inline-block; font-family: var(--sans); font-weight: 800; font-size: 15px;
  letter-spacing: 5px; text-transform: uppercase; background: var(--red); color: var(--cream);
  padding: 7px 18px 6px; transform: rotate(-2deg); text-indent: 5px; }
.news-head { margin-top: 16px; }
.news-head div { font-family: var(--display); font-weight: 900; font-size: 104px; text-transform: uppercase;
  line-height: .98; white-space: nowrap; overflow: hidden; width: 988px; }
.news-head .news-v { font-style: italic; font-size: 44px; color: var(--red); line-height: 1.1; }
.news-badges { display: flex; align-items: center; justify-content: center; gap: 30px; margin-top: 22px; }
.tpl-frontpage .news-badges .fx-badge { width: 120px; height: 120px; padding: 14px; }
.news-sub { font-family: var(--marker); font-size: 36px; color: var(--red); transform: rotate(-2deg);
  margin-top: 18px; }
.news-cols { flex: 1 1 auto; min-height: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0; border-top: 3px solid var(--ink); border-bottom: 3px solid var(--ink); }
.news-col { padding: 18px 20px; box-sizing: border-box; min-width: 0; overflow: hidden;
  display: flex; flex-direction: column; justify-content: center; }
.news-col + .news-col { border-left: 2px solid var(--ink); }
.col-kick { font-family: var(--sans); font-weight: 700; font-size: 13px; letter-spacing: 4px;
  text-transform: uppercase; color: var(--red); }
.col-badges { display: flex; gap: 10px; margin: 14px 0; }
.news-col .row-badge { width: 56px; height: 56px; padding: 6px; }
.col-teams div { font-family: var(--display); font-weight: 900; font-size: 34px; text-transform: uppercase;
  line-height: 1.05; white-space: nowrap; overflow: hidden; }
.col-body { font-family: var(--sans); font-weight: 500; font-size: 19px; line-height: 1.45;
  color: var(--line); margin-top: 12px; }

/* ---- HERO: one player filling a night poster ---- */
.art-hero { flex: 1 1 auto; min-height: 0; position: relative; overflow: hidden; border-radius: 16px;
  border: 3px solid var(--cream); box-sizing: border-box; background-color: var(--ink-4);
  background-image:
    repeating-linear-gradient(115deg, rgba(246, 242, 234, .035) 0 1px, rgba(246, 242, 234, 0) 1px 9px),
    linear-gradient(180deg, #3a3128 0%, #2a221a 60%, #1e1812 100%); }
.hero-name-bg { position: absolute; left: -10px; top: 40px; font-family: var(--display); font-weight: 900;
  font-size: 300px; line-height: .85; color: var(--cream); opacity: .08; white-space: nowrap;
  pointer-events: none; }
.tpl-hero .slot-wash { top: 18%; left: auto; right: -12%; width: 70%; transform: none; opacity: .18; }
.hero-stage { position: absolute; top: 0; right: 0; bottom: 0; width: 60%; overflow: hidden;
  display: flex; align-items: flex-end; justify-content: center; }
.hero-stage img, .split-side img { position: absolute; display: block; max-width: none;
  transform-origin: center center; }
.hero-scrim { position: absolute; top: 0; left: 0; right: 0; bottom: 0; pointer-events: none;
  /* the foot layer hides the flat bottom edge cut-outs usually end in */
  background:
    linear-gradient(0deg, rgba(21, 17, 13, .92) 0%, rgba(21, 17, 13, .92) 6%, rgba(21, 17, 13, 0) 24%),
    linear-gradient(90deg, rgba(21, 17, 13, .78) 0%, rgba(21, 17, 13, .35) 45%, rgba(21, 17, 13, 0) 70%); }
.hero-info { position: absolute; left: 36px; bottom: 36px; width: 56%; z-index: 2;
  display: flex; flex-direction: column; align-items: flex-start; pointer-events: none; }
.hero-kick { font-family: var(--sans); font-weight: 700; font-size: 15px; letter-spacing: 5px;
  text-transform: uppercase; color: var(--muted); }
.hero-player { align-self: stretch; max-width: 100%; margin-top: 8px; font-family: var(--display);
  font-weight: 900; font-size: 96px; line-height: .95; color: var(--yellow); text-transform: uppercase;
  white-space: nowrap; overflow: hidden; }
.hero-club { margin-top: 10px; font-family: var(--sans); font-weight: 800; font-size: 18px;
  letter-spacing: 4px; text-transform: uppercase; color: var(--cream); }
.hero-fx { align-self: stretch; max-width: 100%; margin-top: 26px; font-family: var(--sans);
  font-weight: 800; font-size: 26px; color: var(--cream); white-space: nowrap; overflow: hidden; }
.hero-when { margin-top: 16px; display: inline-block; font-size: 30px; }
.hero-note { margin-top: 18px; display: inline-block; }

/* ---- SPLIT: two players on a yellow / ink diagonal ---- */
.art-split { flex: 1 1 auto; min-height: 0; position: relative; overflow: hidden; border-radius: 16px;
  border: 3px solid var(--cream); box-sizing: border-box;
  background: linear-gradient(104deg, var(--yellow) 0 49.6%, var(--ink) 50.4% 100%); }
.split-side { position: absolute; top: 0; bottom: 0; width: 50%; overflow: hidden; display: flex;
  align-items: flex-end; justify-content: center; }
.split-side.a { left: 0; }
.split-side.b { right: 0; }
.split-club { position: absolute; top: 22px; z-index: 1; font-family: var(--sans); font-weight: 800;
  font-size: 15px; letter-spacing: 3px; text-transform: uppercase; padding: 7px 16px 6px;
  border-radius: 999px; pointer-events: none; }
.split-club.a { left: 22px; background: var(--ink); color: var(--yellow); }
.split-club.b { right: 22px; background: var(--yellow); color: var(--ink); }
.split-vs { position: absolute; top: 46%; left: 50%; width: 138px; height: 138px; margin: -69px 0 0 -69px;
  border-radius: 50%; box-sizing: border-box; background: var(--yellow); border: 5px solid var(--ink);
  border-width: 5px 10px 10px 5px; display: flex; align-items: center; justify-content: center; z-index: 2;
  font-family: var(--display); font-weight: 900; font-size: 54px; letter-spacing: 1px; color: var(--ink);
  transform: rotate(-10deg); pointer-events: none; }
/* a dark foot under each name: the cut-outs end in a flat edge, and ink on the yellow half
   cannot be read over a red shirt */
.split-cap { position: absolute; bottom: 0; z-index: 1; width: 50%; box-sizing: border-box;
  padding: 70px 26px 26px; pointer-events: none;
  background: linear-gradient(180deg, rgba(21, 17, 13, 0) 0%, rgba(21, 17, 13, .88) 62%); }
.split-cap.a { left: 0; }
.split-cap.b { right: 0; text-align: right; }
.split-cap .n { font-family: var(--display); font-weight: 900; font-size: 54px; line-height: 1.05;
  text-transform: uppercase; white-space: nowrap; overflow: hidden; }
.split-cap .n { color: var(--cream); }
.split-cap .s { font-family: var(--sans); font-weight: 700; font-size: 14px; letter-spacing: 3px;
  text-transform: uppercase; margin-top: 6px; }
.split-cap .s { color: var(--yellow); }
.split-strip { flex: 0 0 auto; display: flex; flex-direction: row; justify-content: space-between;
  align-items: center; gap: 20px; }
.split-strip .title-hand { margin-top: 0; }
.split-strip .title-note { margin-top: 0; }

/* ---- LINE-UP: schedule rows, then one player per game ---- */
.lineup-rows { flex: 0 0 auto; display: flex; flex-direction: column; }
.tpl-lineup .row-line { flex: 0 0 60px; }
.art-lineup { flex: 1 1 auto; min-height: 0; display: grid; gap: 14px; grid-template-rows: minmax(0, 1fr); }

#artwork.editing .hero-stage.picked, #artwork.editing .split-side.picked {
  outline: 3px dashed rgba(245, 213, 71, .7); outline-offset: -10px; }
