/* The printed اطلاعنومه. One A4 page, dark ink on white.
   =========================================================================

   Loaded with media="print", so none of it touches the screen. That also
   makes it testable: flipping the <link>'s media to "all" renders the exact
   print layout in a browser, which is how the one-page fit was measured
   rather than guessed - and how the token reset below was checked against
   the dark theme.

   The layout target is A4 at 10mm margins - 190 x 277mm, about 718 x 1047
   CSS pixels. Everything below is sized so a class of eighteen subjects
   still lands on a single sheet.

   Design rules for paper, which are not the screen's rules:
     - No filled backgrounds. A cheap shop printer renders tints as grey mud,
       and the office prints hundreds of these.
     - Hairline rules instead of cards. Borders print; shadows and radii do
       not, and half-rendered rounded boxes look like a fax.
     - Everything is black. Colour is a screen affordance; on paper the
       pass/fail word carries the meaning on its own.
   ========================================================================= */

@page {
  size: A4;
  /* 10mm rather than 12: a full subject list plus the stamp needs the
      height, and 10mm still clears every desktop printer's dead zone. */
  margin: 10mm;

  /* Keeps the browser's own header and footer - the date and time, the page
     title, the web address and "1/2" - off every printed page. Chrome and
     Edge print their own text in a page margin only while the page leaves
     that margin empty; claiming one box at the top and one at the bottom,
     even with nothing in them, hands both margins to the document. Measured
     on Edge 154: one box removes its own edge's text, both remove all of it.
     Firefox does not support margin boxes; there the "Headers and footers"
     box in the print dialog still decides, and it remembers the choice. */
  @top-left { content: ''; }
  @bottom-left { content: ''; }
}

/* Paper has no dark mode. Every rule below states its colour in hex for
   exactly this reason, but the app's own rules do not - they read --fg,
   --fg-muted, --glass and so on, and since the office app now defaults to
   dark those resolve to near-white. Anything this file does not explicitly
   override would print white ink on white paper.

   Rather than chase each one, the tokens themselves are forced back to the
   light values for print. This costs one block and cannot be got wrong later
   by someone adding a component that happens to use a token. */
:root,
:root[data-theme='dark'] {
  --bg: #ffffff;
  --surface: #ffffff;
  --surface-alt: #ffffff;
  --glass: transparent;
  --glass-strong: transparent;
  --glass-border: #999999;
  --wash-a: transparent;
  --wash-b: transparent;
  --border: #999999;
  --border-strong: #666666;
  --fg: #000000;
  --fg-muted: #333333;
  --fg-subtle: #444444;
  --field-line: #666666;
  --field-label: #333333;
  --shadow-sm: none;
  --shadow: none;
  --shadow-lg: none;
}

/* !important because the palette files load after this one and re-state
   --bg for the dark theme. Without it a page printed from dark mode gets a
   black band in the margins, since the page margin shows the root's ground. */
html,
body {
  background: #fff !important;
  color: #000;
  font-size: 9.5pt;
  line-height: 1.35;
}

/* ---------------------------------------------------------- app chrome */

/* Everything that is interface rather than document. */
.topbar,
.hero,
.guide,
.toasts,
.appbar,
.nav,
.nav-backdrop,
.toolbar,
.page-head,
.card__head,
.card__foot,
.modal__head,
.modal__foot,
.no-print {
  display: none !important;
}

.wrap,
.main {
  padding: 0 !important;
  max-width: none !important;
}
.portal-grid,
.app {
  display: block !important;
}

.card {
  border: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  background: none !important;
}
.card__body {
  padding: 0 !important;
}

/* Printing from the office: the card is cloned into #print-root in the
   normal document flow, and everything else steps out of the way. Printing
   the <dialog> itself would mean printing top-layer content, which browsers
   disagree about. */
html.is-printing body > *:not(#print-root) {
  display: none !important;
}
html.is-printing #print-root {
  display: block !important;
}

/* Belt and braces for anyone who hits Ctrl+P with the dialog open: it stops
   being a floating panel and becomes the page. */
dialog.modal {
  position: static !important;
  display: block !important;
  max-width: none !important;
  max-height: none !important;
  width: auto !important;
  overflow: visible !important;
  border: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  background: none !important;
  padding: 0 !important;
}
dialog.modal::backdrop {
  display: none !important;
}

.print-only {
  display: block !important;
}

/* ---------------------------------------------------------- letterhead */

.letterhead {
  display: flex !important;
  align-items: center;
  gap: 10px;
  padding-block-end: 5px;
  margin-block-end: 8px;
  border-block-end: 1.5pt solid #000;
}
.letterhead img {
  width: 38px;
  height: 38px;
}
.letterhead__name {
  font-size: 14pt;
  font-weight: 700;
  line-height: 1.15;
}
.letterhead__sub {
  font-size: 8.5pt;
  color: #333;
}

/* ------------------------------------------------------------ identity */

.idblock {
  border: none;
  background: none;
  padding: 0;
  margin-block-end: 8px;
}
.idblock__head {
  gap: 9px;
  margin-block-end: 6px;
}
.idblock__head .avatar {
  width: 40px;
  height: 40px;
  border: 0.75pt solid #999;
  background: none;
  color: #000;
  font-size: 12pt;
}
.idblock__head h3 {
  font-size: 12pt;
}
/* Redundant with the letterhead two lines above it. */
.idblock__head .subtle {
  display: none !important;
}
/* The chips repeat the summary block four lines further down. On a page
   this tight, saying it once is worth more than saying it twice. */
.idblock__head .row {
  display: none !important;
}

/* The screen version is one panel whose dividers are the grid gap showing a
   background through it. On paper that would print as a grey slab behind the
   gaps and a rounded outline that no official document wants, so the ground
   comes off and the cells go back to carrying their own rules. Fixed at three
   columns here regardless of paper width. */
.idgrid {
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  background: none;
  border: none;
  border-radius: 0;
  overflow: visible;
}
.idfield {
  border: 0.75pt solid #999;
  border-inline-start: 2pt solid #000;
  border-radius: 0;
  background: none;
  padding: 2px 6px;
}
.idfield__label {
  font-size: 7.5pt;
  color: #444;
}
.idfield__value {
  font-size: 9pt;
  line-height: 1.2;
}
/* Muted on screen so it recedes; on paper it only needs to not be black. */
.idfield--empty .idfield__value {
  color: #444;
  font-weight: 500;
}

/* --------------------------------------------------------------- marks */

.section {
  margin-block-end: 5px;
}
.section__head {
  margin-block-end: 4px;
  gap: 6px;
}
.section__head h4 {
  font-size: 10pt;
}
.section__head .chip {
  border: none;
  background: none !important;
  color: #333 !important;
  padding: 0;
  font-size: 8pt;
  font-weight: 600;
}

.tablewrap {
  border: 0.75pt solid #666;
  border-radius: 0;
  overflow: visible !important;
  background: none;
}
table {
  font-size: 8pt;
}
thead th {
  position: static;
  padding: 3px 6px;
  font-size: 7pt;
  letter-spacing: 0;
  color: #000;
  background: none !important;
  border-block-end: 1pt solid #000;
}
thead th .subtle {
  font-size: 7pt;
  color: #444;
}
tbody td {
  padding: 2px 6px;
  border-block-end: 0.5pt solid #bbb;
}
tbody tr:hover td {
  background: none !important;
}
/* A long subject list may spill; splitting a ROW would be unreadable, and a
   spilled table needs its header again. */
thead {
  display: table-header-group;
}
tr {
  break-inside: avoid;
}

/* The pass/fail column: on paper the word is the signal, so the chip loses
   its pill and its colour and becomes plain text. */
td .chip {
  border: none !important;
  background: none !important;
  color: #000 !important;
  padding: 0;
  font-size: 8pt;
  font-weight: 700;
}
td .chip__dot {
  display: none !important;
}
td.mark--fail {
  color: #000 !important;
  font-weight: 700;
  text-decoration: underline;
}

/* ------------------------------------------------- summary & attendance */

/* Two blocks side by side rather than stacked - this pairing is what buys
   the page back. */
.card__body > .section:nth-last-of-type(2),
.card__body > .section:nth-last-of-type(1) {
  break-inside: avoid;
}

.print-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  align-items: start;
  margin-block-end: 9px;
}

/* On screen these are cubby cards in an auto-fit grid. On paper that goes
   ragged - seven stats over three columns leaves a lone cell on its own row,
   which reads as a mistake rather than a layout. Printed, they become plain
   label/value rows in two columns inside one ruled box: shorter, never
   ragged, and it looks like the official form it is. */
.statgrid {
  display: grid !important;
  grid-template-columns: 1fr 1fr !important;
  gap: 0 10px !important;
  margin-block: 0 !important;
  border: 0.75pt solid #999;
  padding: 3px 7px;
}
.stat {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  border: none;
  border-radius: 0;
  border-block-end: 0.5pt dotted #bbb;
  background: none !important;
  padding: 2px 0;
}
/* The cubby pegs are a screen motif. On paper they are two grey dots and a
   22px gap that buys nothing. */
.stat::before,
.stat::after {
  display: none !important;
}
.stat__label {
  font-size: 7.5pt;
  letter-spacing: 0;
  text-transform: none;
  font-weight: 600;
  color: #333;
  margin: 0;
}
.stat__value {
  font-size: 9.5pt;
  font-weight: 700;
  color: #000 !important;
  white-space: nowrap;
}
/* The result and any failure count still need to stand out, but with weight
   and a rule rather than a filled box. */
.stat--pass,
.stat--fail {
  background: none !important;
  border-block-end: 1pt solid #000;
}
.stat--pass .stat__value,
.stat--fail .stat__value {
  font-size: 10pt;
}
/* An odd number of stats leaves the last row half empty; a trailing rule
   under it reads as a missing value. */
.statgrid .stat:last-child {
  border-block-end: none;
}

/* ------------------------------------------- achievement and the stamp */

/* The badge and the stamp share one row: both are small, and side by side
   they read as the footer of a certificate rather than two loose panels. */
.print-footer {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  align-items: stretch;
  margin-block-start: 4px;
  break-inside: avoid;
}

/* The screen colours each grade band - green through amber to red - with
   [data-grade] selectors, which outrank a bare .achievement here. Paper gets
   none of it: these need !important or a C badge prints an amber border. */
.achievement {
  margin: 0;
  padding: 7px 9px;
  gap: 9px;
  border: 0.75pt solid #999 !important;
  border-radius: 0;
  background: none !important;
}
.achievement__badge {
  width: 42px;
  height: 42px;
  font-size: 18pt;
  border: 1.5pt solid #000 !important;
  border-radius: 0 !important;
  background: none !important;
  color: #000 !important;
  box-shadow: none !important;
}
.achievement__title {
  font-size: 11pt;
  margin-block: 0 3px;
}
.achievement__note {
  font-size: 7pt;
  line-height: 1.35;
  color: #333;
}
.achievement .subtle {
  font-size: 7pt;
}

.stamp {
  margin: 0;
  padding: 7px 9px;
  gap: 9px;
  border: 1pt solid #000;
  border-radius: 0;
  background: none !important;
  flex-wrap: nowrap;
  align-items: center;
}
.stamp__qr {
  width: 66px;
  height: 66px;
  padding: 0;
  border: none;
  background: none;
}
.stamp__title {
  font-size: 8.5pt;
  margin-block-end: 2px;
}
.stamp__rows {
  display: block;
  font-size: 7.5pt;
  line-height: 1.5;
}
.stamp__print {
  font-size: 11pt;
  color: #000 !important;
  letter-spacing: 0.14em;
}
.stamp__hint {
  font-size: 6pt;
  line-height: 1.35;
  margin-block-start: 3px;
  color: #333;
  max-width: none;
}
.stamp__seal {
  width: 66px;
  height: 66px;
  border-width: 1.5pt;
  border-color: #000;
  color: #000;
}
.stamp__seal-ring {
  width: 55px;
  height: 55px;
  border-color: #000;
  padding: 3px;
}
.stamp__seal-top,
.stamp__seal-bottom {
  font-size: 5pt;
  opacity: 1;
}
.stamp__seal-code {
  font-size: 12pt;
  margin-block: 1px;
}

/* ----------------------------------------------------------- footnote */

.footnote {
  margin-block-start: 6px;
  padding: 3px 8px;
  border: 0.5pt solid #999;
  border-radius: 0;
  font-size: 7.5pt;
  color: #333;
}

.signature-row {
  display: flex !important;
  justify-content: space-between;
  gap: 14px;
  margin-block-start: 18px;
  break-inside: avoid;
}
.signature-row > div {
  flex: 1;
  border-block-start: 0.75pt solid #000;
  padding-block-start: 3px;
  text-align: center;
  font-size: 8pt;
}

/* Screen-only affordances that make no sense on paper. */
.empty,
.spinner,
.alert {
  color: #000;
}
.alert {
  border: 0.75pt solid #999;
  background: none !important;
  font-size: 8pt;
  padding: 4px 8px;
}

/* =========================================================================
   COLOUR ON PAPER
   =========================================================================

   This block deliberately relaxes the third design rule at the top of this
   file - "Everything is black" - and softens the first. Read that header
   before changing anything here, because the reasoning behind it has not
   gone away; it has been traded off on purpose.

   What the trade buys: the report card the family keeps looks like a
   document the school is proud of rather than a database printout, and the
   failed rows are findable in one glance instead of one read.

   What it costs, and how each cost is contained:

     Toner. Colour is spent on RULES and TEXT, which cost almost nothing,
     and on tints only where they earn their place - the table header and
     the failed rows. Every tint is above 94% lightness, so a tired shop
     printer renders it as a faint wash rather than the grey mud the header
     warns about.

     Greyscale printers. Nothing here carries meaning by colour alone. The
     RESULT column still says Passed or Failed in words, a failed mark is
     still bold and still underlined, and the failed row still has a solid
     edge on the reading side. Print this in black and white and you lose
     decoration, not information.

   Browsers strip background colours from printouts by default, so without
   the print-color-adjust rule below every tint in this block would silently
   not print and the whole thing would look exactly as it did before. */

* {
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

:root,
:root[data-theme='dark'] {
  /* The blue the parent already sees on the portal, so the paper and the
     screen are recognisably one product. */
  --pr-accent: #00719c;
  --pr-accent-soft: #e6f4fa;
  --pr-rule: #cfd4dd;
  /* Both dark enough to read as text on white, and far enough apart in
     LIGHTNESS - not just hue - to stay distinguishable in greyscale. */
  --pr-pass: #177e3d;
  --pr-fail: #dd001c;
  --pr-fail-soft: #fff0f2;
}

/* --- letterhead --- */
.letterhead {
  border-block-end: 1.5pt solid var(--pr-accent);
}
.letterhead__name {
  color: var(--pr-accent);
}

/* --- identity --- */
/* Was a 2pt black bar on every field, which read as six heavy tally marks
   down the page. Same job, in the document's own colour. */
.idfield {
  border-color: var(--pr-rule);
  border-inline-start-color: var(--pr-accent);
}
.idfield__label {
  color: var(--pr-accent);
}
.idblock__head .avatar {
  border-color: var(--pr-accent);
}

/* --- section headings --- */
.section__head h4 {
  color: var(--pr-accent);
}

/* --- tables --- */
.tablewrap {
  border-color: var(--pr-accent);
}
thead th {
  color: var(--pr-accent) !important;
  background: var(--pr-accent-soft) !important;
  border-block-end: 1pt solid var(--pr-accent);
}
thead th .subtle {
  color: var(--pr-accent) !important;
}
tbody td {
  border-block-end: 0.5pt solid var(--pr-rule);
}
/* Zebra striping at a lightness a cheap printer cannot turn to mud. Reading
   across eighteen rows of numbers is the one thing this table asks of a
   parent, and the stripe is what keeps the eye on the line. */
tbody tr:nth-child(even) td {
  background: #f4f6f9;
}

/* --- pass and fail --- */
/* The chip still loses its pill on paper - a printed badge looks like a
   sticker - but it keeps the colour now. The word is unchanged, so this is
   reinforcement, never the signal itself. */
td .chip {
  font-weight: 700;
}
td .chip--pass {
  color: var(--pr-pass) !important;
}
td .chip--fail {
  color: var(--pr-fail) !important;
}
td.mark--fail {
  color: var(--pr-fail) !important;
  /* bold and underline stay: this has to survive a greyscale printer */
}
/* The whole failed row, so it is findable while turning the page rather than
   while reading it. :has() is a progressive enhancement - where it is not
   supported the row simply looks like the others and the coloured, bold,
   underlined mark still carries it. */
tbody tr:has(.chip--fail) td {
  background: var(--pr-fail-soft);
}
tbody tr:has(.chip--fail) td:first-child {
  box-shadow: inset 2pt 0 0 var(--pr-fail);
}
[dir='rtl'] tbody tr:has(.chip--fail) td:first-child {
  box-shadow: inset -2pt 0 0 var(--pr-fail);
}

/* --- summary and attendance --- */
.statgrid {
  border-color: var(--pr-accent);
}
.stat {
  border-block-end-color: var(--pr-rule);
}
.stat--pass {
  border-block-end: 1pt solid var(--pr-pass);
}
.stat--fail {
  border-block-end: 1pt solid var(--pr-fail);
}
.stat--pass .stat__value {
  color: var(--pr-pass) !important;
}
.stat--fail .stat__value {
  color: var(--pr-fail) !important;
}

/* --- the achievement badge ---

   The rule above this block strips the grade colours on purpose - "Paper
   gets none of it: these need !important or a C badge prints an amber
   border." That was the right call while paper was monochrome. It is not the
   right call now, because this band is the one piece of colour on the sheet
   that a child looks for first, and the green-through-red scale already
   means something.

   Pinned hex rather than the --grass / --marigold / --coral tokens the
   screen uses, for two reasons: the screen's light palette re-points coral
   and teal to blue, and the dark theme's crayons are light tints that would
   print as barely-there. A printed grade band should not change because
   somebody had dark mode on when they hit print. */
.achievement[data-grade='a-plus'] { border-color: #177e3d !important; background: #e9fbf0 !important; }
.achievement[data-grade='a']      { border-color: #157b69 !important; background: #e8fbf7 !important; }
.achievement[data-grade='b']      { border-color: #0375a8 !important; background: #ecf9fe !important; }
.achievement[data-grade='c']      { border-color: #856c00 !important; background: #fdf6d8 !important; }
.achievement[data-grade='d']      { border-color: #dd001c !important; background: #fff0f2 !important; }
.achievement[data-grade='f'],
.achievement.achievement--fail[data-grade] {
  border-color: var(--pr-fail) !important;
  background: var(--pr-fail-soft) !important;
}

.achievement[data-grade='a-plus'] .achievement__badge { border-color: #177e3d !important; color: #177e3d !important; }
.achievement[data-grade='a'] .achievement__badge      { border-color: #157b69 !important; color: #157b69 !important; }
.achievement[data-grade='b'] .achievement__badge      { border-color: #0375a8 !important; color: #0375a8 !important; }
.achievement[data-grade='c'] .achievement__badge      { border-color: #856c00 !important; color: #856c00 !important; }
.achievement[data-grade='d'] .achievement__badge      { border-color: #dd001c !important; color: #dd001c !important; }
.achievement[data-grade='f'] .achievement__badge,
.achievement.achievement--fail[data-grade] .achievement__badge {
  border-color: var(--pr-fail) !important;
  color: var(--pr-fail) !important;
}

/* --- the verification stamp --- */
.stamp {
  border-color: var(--pr-accent);
}
.stamp__title {
  color: var(--pr-accent);
}

/* ---------------------------------------------------------------- timetable

   Six days across A4 portrait is tight but readable, and portrait is what
   @page above sets for the report card - the document this school prints far
   more often. Rather than fight it, the grid is simply made smaller: the
   cells carry three short lines, and the room is the line that goes when
   there is no space for three.

   A lesson must not be split across a page break. A timetable cut through
   the middle of Tuesday is worse than one that starts on a second sheet. */
table.tt {
  min-width: 0;
  font-size: 8.5pt;
  page-break-inside: auto;
}
table.tt thead th {
  padding: 4pt 3pt;
  font-size: 7.5pt;
  color: #000000;
  background: #eeeeee !important;
  border: 0.5pt solid #999999;
}
table.tt tbody th {
  padding: 4pt 3pt;
  background: #f6f6f6 !important;
  border: 0.5pt solid #999999;
}
table.tt tbody td {
  padding: 2pt;
  border: 0.5pt solid #999999;
}
table.tt tr { page-break-inside: avoid; }

.tt-cell {
  min-height: 0;
  padding: 2pt 3pt;
  border: none;
  border-radius: 0;
  background: transparent !important;
  gap: 0;
}
.tt-cell__subject { font-size: 8.5pt; font-weight: 700; color: #000000; }
.tt-cell__teacher { font-size: 7pt; color: #333333; }
.tt-cell__room { font-size: 7pt; color: #444444; }
/* An empty slot prints as an empty box, not as a dashed one - the dashes
   cost toner and say nothing on paper, where nothing can be clicked. */
.tt-cell--free { border: none; }
.tt-period__no { font-size: 8.5pt; font-weight: 700; }
.tt-period__time { font-size: 7pt; color: #333333; }

.tt-row--break th,
.tt-break {
  background: #f0f0f0 !important;
  color: #333333;
  font-size: 7.5pt;
  text-align: center;
}

/* The add-a-lesson buttons are interface. */
.tt-cell--add { display: none !important; }
