/* 4devs.eu - Chess Code: first-visit tutorial (in-page home takeover). */

.cct-page{
  opacity:0; transform:translateY(10px); transition:opacity .4s ease, transform .4s ease;
  padding:clamp(24px,4vw,56px) 0;
}
.cct-page.cct-in{ opacity:1; transform:none; }
/* ONE centred column, board on top, text under it. It was two columns - board
   left, prose right - which reads like documentation: two things competing for
   where your eye starts. A lesson should present one thing at a time, in
   reading order, so the board is the subject and the text is the caption. The
   old grid is kept as a wide-screen fallback below 0 lines only in spirit; at
   every width this is now a single column. */
.cct-inner{
  max-width:560px; margin:0 auto; padding:0 clamp(16px,5vw,28px);
  display:flex; flex-direction:column; align-items:center; gap:18px;
}
.cct-side{ width:100%; text-align:center; }
.cct-stage{ text-align:left; }

/* ---------- progress ---------- */
/* border-box, NOT content-box. With content-box the horizontal padding was
   ADDED to the 100% width, so the bar was always wider than the screen and the
   first segment ran off the left edge - most visible on a phone, where the
   overflow is a bigger share of the width. */
.cct-progress{
  display:flex; gap:6px; width:100%; max-width:560px;
  margin:0 auto 22px; padding:0 clamp(16px,5vw,28px); box-sizing:border-box;
}
.cct-seg{
  flex:1; height:10px; border-radius:100px;
  background:var(--plaster); border:2px solid var(--ink);
  /* Fills left to right as you advance. The transition is on background so a
     newly reached segment fills rather than snapping. */
  transition:background-color .3s ease;
}
.cct-seg-on{ background:var(--sun); }

/* ---------- controls, close under the lesson and centred ----------
   Not a full-width row any more. Stretching Next across the column pinned it
   to the left edge of the page while everything above it was centred, so the
   one control you look at every step was the only thing out of alignment.
   The pair is now a centred group sitting right under the content. */
.cct-controls{
  max-width:560px; margin:14px auto 0; padding:0 clamp(16px,5vw,28px);
  display:flex; justify-content:center;
}
.cct-navrow{ display:flex; gap:10px; justify-content:center; align-items:center; }
/* Next is the action, Back the escape: Next is wider, both are fixed so the
   group stays centred no matter which step is showing. */
.cct-navrow .cct-back{ flex:0 0 auto; min-width:96px; }
.cct-navrow .cct-next{ flex:0 0 auto; min-width:168px; }

/* .cct-badge and #cctBadge were removed on 2026-09-06. The badge only ever
   held the intro step's "e4 = column 5, row 4", cut because it answered a
   question the reader has not asked yet - step 2 shows the same thing
   happening, which teaches it faster. Nothing renders it now, so the rules
   are gone rather than left to rot. */

@media (prefers-reduced-motion: reduce){
  .cct-seg{ transition:none; }
}

.cct-boardwrap{ display:flex; flex-direction:column; align-items:center; gap:16px; }
.cct-board{
  /* svh, not vh or dvh. The board is SQUARE and sized off viewport height, so
     any height change resizes it in both axes - very visible. vh is measured
     with the mobile address bar collapsed (too tall, board overflows when the
     bar is showing) and dvh updates live as the bar slides, which makes the
     board pulse the whole time you scroll. svh is the bar-visible height and
     never changes, so the board holds still. vh first as a fallback. */
  width:min(52vh,380px); width:min(52svh,380px); aspect-ratio:1/1; display:grid;
  grid-template-columns:repeat(8,1fr); grid-template-rows:repeat(8,1fr);
  border-radius:10px; overflow:hidden; box-shadow:0 14px 40px rgba(18,38,43,.22);
  position:relative; border:2px solid var(--cb-navy, #17324A);
  opacity:0; animation:cctBoardIn .85s ease .1s forwards;
}
@keyframes cctBoardIn{ to{ opacity:1; } }
/* Always shown White-at-bottom: grid-row === rank (see chess-tutorial.js),
   flipped visually here so rank 1 lands at the bottom. Squares/pieces
   counter-flip themselves individually (transform is a separate property
   from the opacity entrance animation above, so they don't fight). */
.cct-board.cct-flip{ transform:scaleY(-1); }
.cct-board.cct-flip .cct-sq{ transform:scaleY(-1); }
.cct-sq{ position:relative; }
.cct-light{ background:#E7ECF1; } .cct-dark{ background:#27494F; }
.cct-piece{ width:82%; height:82%; object-fit:contain; align-self:center; justify-self:center;
  z-index:2; transform:translate(0,0); filter:drop-shadow(0 1px 1px rgba(18,38,43,.28)); pointer-events:none; }
.cct-sq.cct-hi{ box-shadow:inset 0 0 0 3px rgba(230,180,68,.95); }
.cct-sq.cct-hi-to{ box-shadow:inset 0 0 0 3px #0F5C74; background:rgba(15,92,116,.16); }

.cct-side{ display:flex; flex-direction:column; }
.cct-kicker{ font-family:var(--mono); font-size:.68rem; text-transform:uppercase; letter-spacing:.12em; color:var(--muted); margin:0 0 8px; }
.cct-title{ font-family:var(--display); font-weight:800; font-size:clamp(1.6rem,3vw,2.1rem); color:var(--ink); margin:0 0 12px; line-height:1.05; }
.cct-text{ font-family:var(--serif); font-size:1.02rem; color:#2B4348; line-height:1.6; margin:0 0 16px; }
.cct-text code{ font-family:var(--mono); font-size:.85em; color:var(--sea); background:rgba(15,92,116,.08); padding:1px 4px; border-radius:4px; }
/* The 120px keeps the layout from jumping as steps of different heights swap
   in. It must NOT apply when the stage is empty, though: the last step has no
   stage at all, so the reserved space pushed "Start playing" a screenful below
   the text it follows. */
.cct-stage{ min-height:120px; margin-bottom:8px; }
.cct-stage:empty{ min-height:0; margin-bottom:0; }

.cct-code{ background:#12262B; color:#E7ECF1; border-radius:9px; padding:16px 16px; margin:0;
  font-family:var(--mono); font-size:.92rem; line-height:1.7; white-space:pre; min-height:96px; }

/* The level cards are the same outlined blocks as the rest of the site, and
   the same shape as the Code skill rows in Profile - which is what these
   describe, so they should look like the thing you will actually be picking.
   Not interactive here (this step explains, it does not set anything), so no
   hover or press: a block that reacts to the pointer but does nothing when
   clicked is worse than one that sits still. */
.cct-levels{ display:flex; flex-direction:column; gap:10px; }
.cct-lvl{
  background:var(--paper); border:2px solid var(--ink); border-radius:10px;
  box-shadow:0 4px 0 var(--ink); padding:12px 14px;
}
.cct-lvl-tag{ display:inline-block; font-family:var(--display); font-weight:700; font-size:.86rem; color:var(--ink); margin-right:8px; }
.cct-lvl-d{ font-family:var(--mono); font-size:.74rem; color:var(--muted); }

.cct-try{ display:flex; flex-direction:column; gap:8px; }
/* The answer line is an editor surface, so it keeps the dark code ground the
   in-game code box uses - but it takes the outline and shadow so it belongs to
   the same family as the tiles feeding into it. */
.cct-try-line{
  background:#12262B; border:2px solid var(--ink); border-radius:10px;
  box-shadow:0 4px 0 var(--ink);
  padding:12px; min-height:48px; display:flex; flex-wrap:wrap; gap:8px; align-items:center;
}
.cct-try-empty{ color:#5C6E72; font-family:var(--mono); font-size:.8rem; font-style:italic; }
/* Placed tiles: same block language, sized down and in the dark palette
   because they sit ON the dark answer line. The shadow is a lighter slate, not
   --ink: an ink shadow on an ink ground is invisible. */
.cct-chip{
  background:#2C4A52; color:#E7ECF1; border:2px solid #0A171B; border-radius:7px;
  box-shadow:0 3px 0 #0A171B;
  padding:5px 10px; font-family:var(--mono); font-weight:700; font-size:.8rem; cursor:pointer;
  transition:filter .18s ease, transform .1s ease, box-shadow .1s ease;
}
.cct-chip:hover{ filter:brightness(1.12); }
.cct-chip:active{ transform:translateY(3px); box-shadow:0 0 0 #0A171B; filter:none; }
.cct-try-bank{ display:flex; flex-wrap:wrap; gap:8px; }
/* Chunky-outlined, same language as the play panel: flat fill, 2px --ink
   outline, hard bottom shadow that compresses on press. Hover is colour-only -
   a bank of tiles that each lift as the pointer crosses them is very twitchy. */
.cct-tile{
  background:var(--paper); border:2px solid var(--ink); border-radius:7px;
  box-shadow:0 3px 0 #B4B0A5;
  padding:7px 13px; font-family:var(--mono); font-size:.84rem; font-weight:600; color:var(--ink);
  cursor:pointer; transition:filter .18s ease, transform .1s ease, box-shadow .1s ease;
}
.cct-tile:hover{ filter:brightness(.94); }
.cct-tile:active{ transform:translateY(3px); box-shadow:0 0 0 #B4B0A5; filter:none; }
.cct-used{ opacity:.28; pointer-events:none; }
/* Centred, not left-aligned. .cct-stage sets text-align:left for the code
   and the tile bank, but this one line is a verdict on what you just did
   and it sits directly above the centred Back/Next group - left-aligned it
   hung off to one side of the only other thing on that part of the screen. */
.cct-try-fb{ font-family:var(--display); font-weight:700; font-size:.84rem; margin:0; min-height:1.2em; text-align:center; }
.cct-ok{ color:var(--ink); }   /* black, not the teal --sea */ .cct-bad{ color:#C0552F; }

/* The .cct-controls rule lives with the layout block near the top of this file
   now. A second definition here won on source order (equal specificity, later
   wins) and quietly cancelled the centred max-width - the same trap that once
   made .cp-back draw a dark arrow on a dark ground. */
/* Back / Next / Run, in the same chunky register as the tiles above. Each
   carries its own --cct-shade (a darkened version of its own fill) rather than
   a shared --ink shadow: --btn-primary is an ink fill, and an ink shadow under
   an ink button is invisible. */
.cct-navrow .btn{
  --cct-shade:#B4B0A5;
  padding:9px 18px; height:auto; font-weight:700;
  border:2px solid var(--ink); border-radius:8px;
  box-shadow:0 4px 0 var(--cct-shade);
  transition:filter .18s ease, transform .1s ease, box-shadow .1s ease;
}
.cct-navrow .btn:hover{ filter:brightness(.94); transform:none; box-shadow:0 4px 0 var(--cct-shade); }
.cct-navrow .btn:active{ transform:translateY(4px); box-shadow:0 0 0 var(--cct-shade); filter:none; }
.cct-navrow .btn-primary{ background:var(--ink); color:var(--paper); --cct-shade:#0A171B; }
.cct-navrow .btn-ghost{ background:var(--paper); color:var(--ink); }
/* Disabled keeps the block shape but must not look pressable: no shadow, so
   it reads as sunk into the page rather than raised off it.

   It is greyed with real colours rather than opacity alone. A faded navy on
   paper still reads as "the dark primary button, dimmed", which is a button
   people keep trying; a flat grey on grey reads as "not yet". The colours are
   forced with !important because .btn-primary sets background and color at
   the same specificity later in the cascade. Disabled controls are exempt
   from the 4.5:1 rule, which is what lets this be quiet enough to read as
   off. Both the tutorial's "watch one move" and "now you try" steps use it. */
.cct-next:disabled{
  cursor:not-allowed; box-shadow:none; transform:none; filter:none;
  background:var(--plaster) !important;
  color:var(--muted) !important;
  border-color:var(--rule) !important;
}
/* And it must not REACT to the pointer while it is off. .cct-navrow .btn:hover
   still applied its brightness filter and .btn:active its press, so a dead
   button dimmed and sank under the cursor exactly like a live one - which is
   the single clearest way to tell someone a control works when it does not.
   Every pointer state is pinned back to the resting one; the moment the step
   enables it, these stop matching and the normal hover comes back on its own. */
.cct-next:disabled:hover,
.cct-next:disabled:active,
.cct-next:disabled:focus{
  background:var(--plaster) !important;
  color:var(--muted) !important;
  border-color:var(--rule) !important;
  filter:none !important; transform:none !important; box-shadow:none !important;
}
@media (prefers-reduced-motion: reduce){
  .cct-tile,.cct-navrow .btn{ transition:none; }
  .cct-tile:active,.cct-navrow .btn:active{ transform:none; }
}

/* Phones: everything a size down so a whole step fits without scrolling.
   The board is sized off viewport height (see .cct-board), so it is the text
   and controls that have to give. */
@media (max-width:560px){
  .cct-progress{ gap:4px; margin-bottom:16px; }
  .cct-seg{ height:8px; }
  .cct-title{ font-size:1.35rem; margin-bottom:8px; }
  .cct-text{ font-size:.92rem; margin-bottom:12px; }
  .cct-inner{ gap:12px; }
  .cct-lvl{ padding:9px 11px; }
  .cct-lvl-tag{ font-size:.8rem; }
  .cct-lvl-d{ font-size:.7rem; }
  .cct-tile{ padding:6px 10px; font-size:.78rem; }
  .cct-chip{ padding:4px 8px; font-size:.76rem; }
  .cct-try-line{ min-height:42px; padding:10px; }
  .cct-navrow .btn{ padding:8px 14px; font-size:.84rem; }
  .cct-navrow .cct-back{ min-width:80px; }
  .cct-navrow .cct-next{ min-width:140px; }
  .cct-controls{ margin-top:10px; }
}

@media (max-width:760px){
  .cct-board{ width:min(74vw,320px); }
  .cct-title{ font-size:1.4rem; }
  .cct-stage{ min-height:0; margin-bottom:4px; }
  .cct-controls{ margin-top:14px; }
}

/* ---------- colored code + counting light-up ---------- */
:root{ --cc-col:#12262B; --cc-row:#12262B; }
.cct-wordmark{ display:inline-flex; align-items:center; text-transform:none; letter-spacing:-.01em;
  font-family:var(--display); font-weight:800; font-size:1.05rem; color:var(--ink); }

/* The typewriter is syntax-highlighted the way an editor would do it, but the
   palette is not an editor theme: grid-column takes the SAME teal the board
   washes down the bottom rule, and grid-row the SAME green it washes up the
   side (.cct-lit-col / .cct-lit-row below). That is the whole teaching trick
   on this screen - the word you are reading and the squares that just lit up
   are one colour, so the link is made without a sentence explaining it.

   The hues are the board's, lightened. The board's own #1C7C9C measures only
   3.30:1 as text on this panel's #12262B, under the 4.5:1 the site commits to
   in ACCESSIBILITY.md - fine as a 45%-alpha wash over a square, not fine as
   9pt mono. Lightening to these two lands both at 5.5:1, matched, still
   unmistakably the board's teal and green. If you retune the washes, retune
   these with them and re-measure against #12262B, not against paper. */
.cct-code .cc-sel{ color:#F5A85C; }
.cct-code .cc-punc{ color:#E7ECF1; opacity:.6; }
.cct-code .cc-prop-col{ color:#25A5D0; }                    /* 5.51:1 on #12262B */
.cct-code .cc-prop-row{ color:#57AC45; }                    /* 5.53:1 on #12262B */
.cct-code .cc-num-col{ color:#25A5D0; font-weight:700; }
.cct-code .cc-num-row{ color:#57AC45; font-weight:700; }
.cct-cursor{ color:#E7ECF1; opacity:.8; }

/* board light-up rulers (bottom = column, left = row) */
.cct-sq::after{ content:''; position:absolute; inset:0; opacity:0; pointer-events:none;
  transition:opacity .4s ease var(--d,0ms); }
.cct-sq.cct-lit-col::after{ background:rgba(28,124,156,.45); opacity:1; }
.cct-sq.cct-lit-row::after{ background:rgba(78,154,62,.45); opacity:1; }

/* coord labels tinted so the counting start is visible */
.cct-coord{ position:absolute; font-family:var(--mono); font-size:.58rem; font-weight:700; pointer-events:none; z-index:3; }
.cct-coord-file{ bottom:2px; right:4px; }
.cct-coord-rank{ top:2px; left:4px; }
/* These carried --cc-col / --cc-row, which is ink by default - and ink on a
   dark square measured 1.6:1, i.e. very nearly invisible. The colour coding
   that teaches column-vs-row is the .cct-lit-col / .cct-lit-row wash on the
   square itself, which is untouched; the label just needs to be readable. */
.cct-light .cct-coord{ color:rgba(18,38,43,.75); }
.cct-dark  .cct-coord{ color:rgba(247,246,242,.8); }
