/* =========================================================
   Sudoku Pro: Rätsel und Trainer - Web-Kostprobe
   Zeitungswelt der iPad-Fassung, portiert nach CSS.

   Die tragende Idee ist die Materialtrennung: Vorgaben sind
   gedruckt (Druckerschwärze, schwerer Schnitt), eigene
   Eingaben sind Bleistift (Graphit, leichter). Alle Töne
   stammen aus Newsprint.swift, die Kontraste sind dort
   gerechnet und hier unverändert übernommen.
   ========================================================= */

.np {
  /* --- Papier und Tinte --- */
  --np-paper:      #DED9CC;  /* Zeitungspapier, grau-tan   */
  --np-ink:        #17150F;  /* Druckerschwärze  12,95:1  */
  --np-graphite:   #4E5868;  /* Brettziffern       5,10:1  */
  --np-note-blue:  #1F4E82;  /* Notiz-Identität    ~7:1   */
  --np-rule:       #635D50;  /* Raster-Haarlinie   4,64:1  */
  --np-rule-faint: #8A8374;  /* rein dekorativ             */
  --np-vermillion: #8E2A1B;  /* einzige Signalfarbe 5,97:1 */
  --np-edge:       #17150F;  /* Brettkante, stärkste Linie */
  --np-cage-line:  rgba(23, 21, 15, .7);    /* Käfiggrenze, gestrichelt */
  --np-peer:       #D6D0C2;  /* Fadenkreuz, abgesenkt      */
  --np-peer-veil:  rgba(23, 21, 15, .10);   /* dasselbe über Käfigton */
  --np-done:       #E7E0C9;  /* fertiger Block, wärmer    */

  /* Käfig-Töne (Killer). Reihenfolge ist Absicht: die beiden
     gegensätzlichsten Töne vorn, weil Welsh-Powell die Plätze
     0 und 1 am häufigsten benachbart vergibt.

     Deckkraft je Ton statt einheitlich: Gold und Oliv liegen dicht
     am Papierton und brauchen mehr, Blau und Pflaume tragen bei
     gleicher Deckung schon weiter. */
  --np-cage-0: rgba(201, 151,  26, .30);  /* Gold    */
  --np-cage-1: rgba( 46,  99, 196, .20);  /* Blau    */
  --np-cage-2: rgba( 29, 163,  94, .24);  /* Grün   */
  --np-cage-3: rgba(154,  63, 196, .20);  /* Pflaume */
  --np-cage-4: rgba( 19, 145, 168, .24);  /* Petrol  */
  --np-cage-5: rgba(143, 168,  28, .30);  /* Oliv    */

  /* Deckkraft der gleichen Ziffer, siehe Tinten-Staffel im Original. */
  --np-same: rgba(23, 21, 15, .06);
}

/* Nachtausgabe, keine Invertierung: eigene Töne je Rolle.
   Die Käfig-Lasur liegt nachts bei 8 statt 10 Prozent - ein heller
   Ton auf fast schwarzem Papier springt bei gleicher Deckung weiter. */
[data-theme="dark"] .np {
  --np-paper:      #26241F;
  --np-ink:        #F0EBDC;
  --np-graphite:   #9FACC0;
  --np-note-blue:  #9CC4EE;
  --np-rule:       #99947F;
  --np-rule-faint: #59564C;
  --np-vermillion: #E8907A;
  --np-edge:       #C9C3B0;
  --np-cage-line:  rgba(240, 235, 220, .55);
  --np-peer:       #312E27;
  --np-peer-veil:  rgba(240, 235, 220, .10);
  --np-done:       #302C21;

  --np-cage-0: rgba(232, 194,  90, .22);
  --np-cage-1: rgba(127, 166, 238, .20);
  --np-cage-2: rgba(111, 203, 155, .20);
  --np-cage-3: rgba(196, 140, 228, .20);
  --np-cage-4: rgba(108, 192, 210, .20);
  --np-cage-5: rgba(195, 213, 102, .22);

  --np-same: rgba(240, 235, 220, .06);
}

/* ============ Bühne ============ */

.np {
  color: var(--np-ink);
  font-family: var(--font-display);
}

.np__stage {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: start;
  padding: clamp(1.25rem, 2.5vw, 2rem);
  border: 2px solid var(--np-rule);
  border-radius: var(--radius);
  background: var(--np-paper);
  box-shadow: var(--shadow-float);
}

/* Nur für Zeigergeräte: unter 1080px wird die Seitenspalte
   untergeschoben statt gequetscht. */
@media (max-width: 1080px) {
  .np__stage { grid-template-columns: minmax(0, 1fr); }
}

/* ============ Kopfleiste: Spielart, Stufe, Level ============ */

.np__picker {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-bottom: 1.25rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--np-rule-faint);
}

.np__group { display: grid; gap: .4rem; }

.np__group-label {
  font-family: var(--font-sans);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--np-graphite);
}

/* Umbrechen muss die Reiterleiste selbst. .np__picker bricht zwar um, schiebt
   damit aber nur die ganze Gruppe in eine eigene Zeile - passt die Gruppe dort
   nicht, läuft sie über den Rand hinaus. Sichtbar wird das nur im schmalen
   Fenster mit Maus: auf dem Telefon zeigt die Seite statt des Bretts den
   Verweis auf die App (siehe .np__touch weiter unten). */
.np__tabs { display: flex; flex-wrap: wrap; gap: .35rem; }

.np__tab {
  min-height: 34px;
  padding: .3rem .8rem;
  border: 1px solid var(--np-rule);
  border-radius: 4px;
  background: transparent;
  color: var(--np-ink);
  font: inherit;
  font-size: .95rem;
  cursor: pointer;
  transition: background .12s var(--ease), color .12s var(--ease);
}

.np__tab:hover { background: var(--np-peer); }

.np__tab[aria-pressed="true"] {
  border-color: var(--np-vermillion);
  background: var(--np-vermillion);
  color: var(--np-paper);
}

.np__tab--num { min-width: 34px; padding: .3rem .55rem; }

/* ============ Brett ============ */

.np__board-wrap { display: grid; justify-items: center; gap: 1rem; }

.np__board {
  display: grid;
  gap: 0;
  width: min(100%, var(--np-board-size, 567px));
  aspect-ratio: 1;
  user-select: none;
}

/* Die Breite wird auf ein Vielfaches der Spaltenzahl abgerundet, damit jede
   Zelle eine ganze Zahl von Punkten breit und hoch ist. Sonst fällt der Rest
   aus der Division auf einzelne Zeilen, und die sehen gequetscht aus - im
   Samurai am ehesten, weil dort 21 Reste zusammenkommen. Zweite Deklaration
   statt einer: Browser ohne round() behalten schlicht die Zeile darüber. */
@supports (width: round(down, 100px, 9px)) {
  .np__board {
    width: round(down, min(100%, var(--np-board-size, 567px)), var(--np-board-step, 9px));
  }
}

.np__board:focus-visible {
  outline: 3px solid var(--np-vermillion);
  outline-offset: 3px;
}

.np__cell {
  position: relative;
  display: grid;
  place-items: center;
  background: var(--np-paper);
  font-size: var(--np-digit-size, 1.6rem);
  line-height: 1;
  cursor: pointer;
}

/* Das Raster liegt als Rahmen-Overlay über der Zelle, nicht als Rand
   an ihr: so verschiebt keine Linienstärke die Geometrie, und jede
   Linie wird genau einmal gezeichnet (Stärken siehe edgeStyle im JS). */
.np__edge {
  position: absolute;
  inset: 0;
  border-style: solid;
  border-width: 0;
  pointer-events: none;
}

/* Rahmenlücke im Samurai: kein Papier, keine Linien, kein Ziel. */
.np__cell--gap {
  background: transparent;
  cursor: default;
  pointer-events: none;
}

/* --- Zellzustände --- */

.np__cell--peer { background: var(--np-peer); }
.np__cell--done { background: var(--np-done); }
.np__cell--same { box-shadow: inset 0 0 0 999px var(--np-same); }

.np__cell--selected {
  box-shadow: inset 0 0 0 2px var(--np-vermillion);
  z-index: 1;
}

/* Der Zeiger bekommt dieselbe Sprache wie die Auswahl, nur leiser. */
.np__cell:not(.np__cell--gap):hover { background: var(--np-peer); }

.np__value { font-variant-numeric: tabular-nums; }

/* Gedruckt: Vorgabe der Redaktion. */
.np__cell--given .np__value {
  color: var(--np-ink);
  font-weight: 700;
}

/* Bleistift: eigene Eingabe. Der leichtere Schnitt trägt die
   Materialtrennung mit, nicht die Farbe allein. */
.np__cell--filled .np__value {
  color: var(--np-graphite);
  font-weight: 400;
}

.np__cell--wrong .np__value { color: var(--np-vermillion); }

.np__cell--revealed .np__value {
  color: var(--np-graphite);
  font-style: italic;
}

/* --- Notizen --- */

.np__notes {
  position: absolute;
  inset: 8%;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  font-family: var(--font-sans);
  font-size: var(--np-note-size, .58rem);
  font-weight: 500;
  line-height: 1;
  color: var(--np-note-blue);
}

.np__notes span { display: grid; place-items: center; }

/* --- Käfige (Killer) --- */

.np__cell--cage { background-color: var(--np-cage-tint, transparent); }

/* Fadenkreuz und Zeiger löschen den Käfigton nicht mehr, sie legen einen
   Schleier darüber - sonst reissen die kräftigeren Lasuren entlang von
   Zeile und Spalte sichtbare Löcher ins Käfigbild. */
.np__cell.np__cell--cage.np__cell--peer,
.np__cell.np__cell--cage:not(.np__cell--gap):hover {
  background-color: var(--np-cage-tint, transparent);
  background-image: linear-gradient(var(--np-peer-veil), var(--np-peer-veil));
}

/* Die Käfiggrenze liegt als gestrichelter Innenrahmen über der Zelle,
   damit sie das Raster nicht verschiebt. Nur Kanten zu *anderen*
   Käfigen werden gezeichnet. */
.np__cage-edge {
  position: absolute;
  inset: 2px;
  pointer-events: none;
  border: 0 dashed var(--np-cage-line);
}

.np__cage-edge--t { border-top-width: 1px; }
.np__cage-edge--r { border-right-width: 1px; }
.np__cage-edge--b { border-bottom-width: 1px; }
.np__cage-edge--l { border-left-width: 1px; }

.np__cage-sum {
  position: absolute;
  top: 4px;
  left: 5px;
  font-family: var(--font-sans);
  font-size: var(--np-sum-size, .64rem);
  font-weight: 700;
  line-height: 1;
  color: var(--np-ink);
}

/* ============ Seitenspalte ============ */

.np__side {
  display: grid;
  gap: 1.25rem;
  align-content: start;
  font-family: var(--font-sans);
}

.np__meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: .3rem 1rem;
  font-size: .9rem;
}

.np__meta dt { color: var(--np-graphite); }
.np__meta dd {
  margin: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--np-ink);
}

.np__status {
  min-height: 3em;
  margin: 0;
  padding: .6rem .75rem;
  border-left: 2px solid var(--np-rule-faint);
  font-size: .9rem;
  color: var(--np-ink);
}

.np__status--win { border-left-color: var(--np-vermillion); font-weight: 600; }

.np__actions { display: grid; gap: .5rem; }

.np__btn {
  min-height: 40px;
  padding: .45rem .9rem;
  border: 1px solid var(--np-rule);
  border-radius: 4px;
  background: transparent;
  color: var(--np-ink);
  font: inherit;
  font-size: .92rem;
  text-align: left;
  cursor: pointer;
  transition: background .12s var(--ease);
}

.np__btn:hover { background: var(--np-peer); }
.np__btn[aria-pressed="true"] {
  border-color: var(--np-vermillion);
  color: var(--np-vermillion);
  font-weight: 600;
}

.np__btn kbd {
  float: right;
  padding: .05rem .3rem;
  border: 1px solid var(--np-rule-faint);
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: .72rem;
  color: var(--np-graphite);
}

.np__keys {
  margin: 0;
  font-size: .82rem;
  line-height: 1.7;
  color: var(--np-graphite);
}

.np__keys dt {
  display: inline-block;
  min-width: 7.5em;
  font-family: var(--font-mono);
  color: var(--np-ink);
}

.np__keys dd { display: inline; margin: 0; }
.np__keys dd::after { content: ""; display: block; }

/* Der Verweis auf die App - die Webfassung ist die Kostprobe,
   nicht das Menü. */
.np__promo {
  padding: .9rem 1rem;
  border: 1px solid var(--np-rule-faint);
  border-radius: 4px;
  font-size: .86rem;
  line-height: 1.55;
  color: var(--np-graphite);
}

.np__promo strong { display: block; color: var(--np-ink); font-size: .95rem; }
.np__promo a { color: var(--np-vermillion); font-weight: 600; }

/* Fussnote zum Stand der App: leiser als der Verweis darüber, ohne Kasten. */
.np__note {
  margin: 0;
  font-size: .8rem;
  line-height: 1.5;
  color: var(--np-graphite);
}

/* ============ Geräte ohne feinen Zeiger ============ */

/* Die Fassung ist auf Tastatur und Zeiger gebaut - ohne beides fehlt der
   halbe Entwurf. Statt einer verkrüppelten Notlösung der ehrliche Verweis
   auf die App, die für den Finger gemacht ist.

   Der Verweis ist der Ausgangszustand, das Brett schaltet sich frei: gefragt
   wird nach `any-pointer`, damit ein Notebook mit Touchscreen - das als
   primäres Zeigegerät den Finger meldet, aber ein Trackpad hat - das Spiel
   bekommt und nicht die Werbung. */
.np__stage { display: none; }

.np__touch {
  display: grid;
  gap: 1rem;
  padding: clamp(1.5rem, 5vw, 2.5rem);
  border: 2px solid var(--np-rule);
  border-radius: var(--radius);
  background: var(--np-paper);
  text-align: center;
}

.np__touch p { margin: 0; color: var(--np-graphite); font-family: var(--font-sans); }

@media (any-pointer: fine) {
  .np__stage { display: grid; }
  .np__touch { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .np__tab, .np__btn, .np__cell { transition: none; }
}
