/* ============================================================
   Resume sheet previews
   ============================================================
   A .sheet is a full-size resume page rendered in the browser:
   816 x 1056 px, which is US Letter at 96dpi. It is the single
   source of truth for what a layout looks like, and it is used
   three ways:

     * the detail page renders one live, so colour and font
       change instantly;
     * tools/render-layout-images.py screenshots the same markup
       with headless Chrome to produce the grid thumbnails, so a
       thumbnail can never disagree with the page it links to;
     * nothing else. The contact form keeps its static radios.

   Two custom properties drive every variant:
       --accent       the colour the client picked
       --font-body    body text
       --font-display the name and section headings

   Everything tinted reads --accent and nothing sets it here, so
   recolouring is one property write on an ancestor.
   ------------------------------------------------------------ */

.sheet {
  --accent: #95684b;
  --font-body: "Lato", system-ui, sans-serif;
  --font-display: "Source Serif Pro", Georgia, serif;
  --ink: #2b2723;
  --muted: #665c51;
  /* The employer/location/dates line. It was #8a7562, which measures
     4.37:1 on white and 3.88:1 on sand -- under AA, and this is not
     decoration: it is where a reader looks for who and when. #79654f
     clears 4.5 on every paper (4.92:1 on sand, the worst) and is still
     visibly quieter than the body ink, which is the whole point of it. */
  --meta: #736050;
  --hair: color-mix(in srgb, var(--accent) 34%, transparent);
  /* --accent is decoration: rules, bars, bullets, panel fills. --accent-ink
     is the same colour at text weight, and the two are separate because one
     of the five schemes cannot do both jobs. Bronze #b08d57 measures 3.09:1
     on white and 2.74:1 on sand — under the 4.5:1 floor for the 12px bold
     section headings, and under even the 3:1 large-text floor — while being
     exactly the right colour for a hairline. Darkening to 68% clears AA on
     every paper (bronze lands at 4.77:1 on the worst compound ground - a washed rail over tinted paper, where two tints stack) and is
     imperceptible on the four schemes that were already dark. */
  --accent-ink: color-mix(in srgb, var(--accent) 68%, #000);

  /* The secondary. Structure is the primary's job; the secondary carries
     incident — bullets, the hairline under a heading, the rail wash, the
     achievement marks. It defaults to a tonal relative of the primary so a
     sheet given only one colour still has two that belong together, rather
     than one colour and a hole. --accent-2-ink is the same darkening the
     primary gets, for the few places the secondary meets text. */
  --accent-2: color-mix(in srgb, var(--accent) 62%, #8a7a63);
  --accent-2-ink: color-mix(in srgb, var(--accent-2) 68%, #000);
  --hair-2: color-mix(in srgb, var(--accent-2) 42%, transparent);
  --paper: #ffffff;

  position: relative;
  width: 816px;
  height: 1056px;
  flex: none;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  /* A named weight ("Lato Light") is the same family at a different cut, so
     the picker carries the weight and the sheet honours it. Defaults to 400
     when a face does not declare one. */
  font-weight: var(--font-body-weight, 400);
  /* --fit is the page solver's (does this fit on the paper); --tidy is the
     line solver's (does each bullet fill one clean line). They are separate
     because they answer different questions and the second must be able to
     move without disturbing the first. */
  font-size: calc(13.4px * var(--fit, 1) * var(--tidy, 1));
  /* The register's leading (brief 7c-3). Deep is 1.45, Light 1.56 —
     tuned against the vertical headroom, not chosen: looser leading
     makes the content taller and clipping a resume is worse than a
     page that is merely less airy. */
  line-height: var(--lead, 1.45);
  padding: 44px 52px;
  overflow: hidden;
  box-sizing: border-box;
  /* Colour and font both animate, so switching either one reads as
     the same object changing rather than a new one appearing. */
  transition: background 0.28s ease, color 0.28s ease;
}

/* ---- shared furniture --------------------------------------- */

.sheet-name {
  font-family: var(--font-display);
  font-size: 38px;
  line-height: 1.04;
  font-weight: 700;
  letter-spacing: 0.2px;
  margin: 0;
  text-transform: uppercase;
}
.sheet-name .given { color: var(--accent-ink); }
.sheet-role { font-size: 15.5px; color: var(--muted); margin: 4px 0 0; font-weight: 400; }
.sheet-contact { font-size: 10.5px; color: var(--muted); margin: 6px 0 0; letter-spacing: 0.2px; }

.sheet h3 {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--accent-ink);
  margin: 0 0 5px;
  padding-bottom: 3px;
  border-bottom: 1px solid var(--hair-2);
}
.sheet-sec + .sheet-sec { margin-top: 1.06em; }

.sheet p { margin: 0 0 2px; }
.sheet ul { margin: 0; padding-left: 13px; list-style: none; }
.sheet li { position: relative; margin: 0 0 0.15em; padding-left: 2px; }
.sheet li::before {
  content: "";
  position: absolute;
  left: -9px; top: 6px;
  width: 3px; height: 3px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 65%, transparent);
}

.sheet-role-title { font-weight: 700; font-size: 1.045em; margin: 0; letter-spacing: 0.2px;
                    text-transform: uppercase; }
.sheet-role-meta { font-size: 0.86em; color: var(--meta); margin: 0 0 0.22em; }
.sheet-lead { margin: 0 0 0.2em; }
.sheet-job + .sheet-job { margin-top: 0.66em; }
.sheet-strong { font-weight: 700; }
.sheet-dim { color: var(--muted); }
.sheet-cols { display: grid; gap: 22px; }
.sheet-body { margin-top: 14px; }

/* ---- Classic --------------------------------------------
   Drawn from the documents Rae builds by hand (Classic 1, 2 and 3 in her
   Drive), not from a sketch. The differences from the rest of the set are
   all deliberate copies of that document:

     * the name sits left, in title case, with the SURNAME carrying the
       colour and the forename in ink — the opposite of every other layout
       here, and the thing that makes it read as hers
     * section headings are title case in the palette's colour, ruled
       across their own column, not letter-spaced capitals
     * the sidebar's skills are plain lines. Bulleting a list of nouns
       adds a mark per line and says nothing
     * no rule under the header: the columns divide the page instead
     * margins and the column split follow the document — 0.3in and a
       2.39/5.51 inch split, which is 30% of the text column

   Page geometry: 0.3in margins at 96dpi is 28.8px, and 30% of the
   remaining 7.9in is the rail. */
.sheet-classic {
  /* Type is taken off the document, not chosen by eye. Classic 2 and 3 set
     the body at 10pt, which is 13.33px at 96dpi -- everything else is a
     multiple of that and is written in pt-derived px below so the two can
     be checked against each other:

         name      44pt   58.7px
         role      18pt   24px
         contact   12pt   16px
         headings  12pt   16px  bold
         body      10pt   13.3px

     The previous values (34 / 16 / 10.6 / 13.5) were about 40% short on the
     name and left the page looking half-used. Margins are the document's
     0.4in; the rail is its 3285/11130 split, which is 29.5%. */
  /* * var(--tidy): the line solver's knob. It was on .sheet only, which
     this rule overrides, so the solver's size search was a no-op on
     Classic -- measured, five candidates, five identical font-sizes. */
  font-size: calc(13.33px * var(--fit, 1) * var(--font-body-scale, 1) * var(--tidy, 1));
  padding: 38px;
}
/* The document's split is 3285/11130 = 29.5%, and at that width two of the
   three award lines wrapped. 31% clears all three, leaves the main column's
   16 bullets on one line apiece, and gives the sheet MORE headroom rather
   than less (-110px against -72px), because the rail is the taller of the
   two columns and widening it shortens it. Measured at four widths; 0.48
   and above start costing the main column. */
.sheet-classic .sheet-cols { grid-template-columns: var(--rail-w, 0.45fr) 1fr; gap: 22px; }

/* ---- the head ----
   No rule beneath it: the columns divide the page, and a horizontal line
   above them is one line too many. */
.sheet-classic .sheet-head {
  text-align: center;
  border-bottom: 0;
  padding-bottom: 14px;
}
/* ANY layout, not just Classic. These were scoped to .sheet-classic, so
   the control existed for one design and silently did nothing for the
   other seven. A head is a head. */
.sheet.head-left .sheet-head,
.sheet.head-left .sheet-headtext { text-align: left; }
.sheet.head-right .sheet-head,
.sheet.head-right .sheet-headtext { text-align: right; }
.sheet.head-center .sheet-head,
.sheet.head-center .sheet-headtext { text-align: center; }

/* Title case, and the surname takes the colour. */
.sheet-classic .sheet-name {
  text-transform: none;
  color: var(--accent-ink);
  font-size: calc(58.7px * var(--fit, 1));
  line-height: 1.02;
  letter-spacing: 0;
}
.sheet-classic .sheet-name .given { color: var(--ink); opacity: 1; }
.sheet-classic .sheet-role {
  font-size: calc(24px * var(--fit, 1));
  line-height: 1.2;
  color: var(--ink);
  font-weight: 400;
  margin-top: 2px;
}
.sheet-classic .sheet-contact {
  margin-top: 8px;
  font-size: calc(16px * var(--fit, 1));
}
/* A mark takes about 175px out of the head, and the contact line is the
   longest single string on the sheet -- at the document's 12pt it wrapped
   onto a second line, which is the same complaint as a bullet that spills
   over. It steps down only in the state that causes it. */
.sheet-classic.head-aside .sheet-contact { font-size: calc(12.5px * var(--fit, 1)); }

/* Headings: capitals, the palette's colour, ruled across their own column.
   Rae's call -- the document sets them title case and she wants caps, which
   at 12pt bold is the difference between a label and a heading. */
.sheet-classic h3 {
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-size: calc(16px * var(--fit, 1));
  font-weight: 700;
  color: var(--accent-ink);
  /* ONE COLOUR. Rae, 2026-09-28: the second colour was too busy, so it
     is gone -- the rules are the primary again, at the weight they were
     when she approved the design. This is also where the current advice
     has been all along: "at most one restrained accent colour". */
  border-bottom: 1px solid color-mix(in srgb, var(--accent) var(--rule-mix, 45%), transparent);
  padding-bottom: 3px;
  margin-bottom: 8px;
}
/* Rhythm. With the type raised to the document's sizes the sheet still ran
   about 165px short, and the difference is spacing, not content -- the
   document sets its bullets and its section gaps looser than the compact
   defaults the other seven layouts share. Set here rather than by growing
   the type again: a resume that fills the page by being large reads as a
   resume with little to say. */
.sheet-classic .sheet-sec + .sheet-sec { margin-top: 1.5em; }
.sheet-classic .sheet-job + .sheet-job { margin-top: 0.85em; }
.sheet-classic .sheet-main li { margin-bottom: 0.3em; }
.sheet-classic .sheet-rail li { margin-bottom: 0.26em; }
.sheet-classic .sheet-role-title { text-transform: none; font-size: 1.03em; margin-top: 0.15em; }
.sheet-classic .sheet-role-meta { font-size: 0.83em; font-style: normal; }

/* ---- dates set against the right edge ----
   The employer, the place and the dates were one run of text separated by
   pipes, which is how a word processor writes a line and not how a page is
   set. Pulling the dates to the right edge of their own column gives the
   entries a second alignment to read down, and it is the cheapest change
   here that makes the page look designed rather than typed.

   The dates keep their element and their source order, so nothing changes
   for a parser: this is alignment, not structure. */
.sheet-classic.dates-aligned .sheet-role-meta {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}
.sheet-classic.dates-aligned .sheet-role-meta .when {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
}

/* Bullets are not optional -- Rae, 2026-09-28. A marker-less variant was
   built and removed: on a resume the dot is doing real work telling a
   reader where one achievement ends and the next begins, and a client is
   not the person to decide otherwise. The rule that drew them is gone
   rather than left unreachable. */

/* The sidebar is a list of nouns, not a list of points. */
.sheet-classic .sheet-rail ul { padding-left: 0; }
.sheet-classic .sheet-rail li { padding-left: 0; margin-bottom: 0.1em; }
.sheet-classic .sheet-rail li::before { display: none; }

/* ---- dividers ----
   Two independent rules, and they used to be one switch plus a rail
   treatment called "ruled". Splitting them is the whole point: a visitor
   who wants the columns divided should not have to accept a rule under
   every heading to get it.

       horizontal   the rules under the section headings
       vertical     the rule between the two columns
       both         the document, and the default
       none         neither

   The vertical rule has to run the full height of the text block, so the
   sheet becomes a column flex and the body takes the slack. A rule that
   stops where the shorter column happens to end reads as an accident. */
.sheet-classic.div-vertical h3,
.sheet-classic.div-none h3 { border-bottom: 0; padding-bottom: 0; }
.sheet-classic.div-vertical .sheet-sec + .sheet-sec,
.sheet-classic.div-none .sheet-sec + .sheet-sec { margin-top: 1.36em; }

.sheet-classic.div-vertical,
.sheet-classic.div-both { display: flex; flex-direction: column; }
.sheet-classic.div-vertical .sheet-body,
.sheet-classic.div-both .sheet-body { flex: 1 1 auto; min-height: 0; }
.sheet-classic.div-vertical .sheet-cols,
.sheet-classic.div-both .sheet-cols { height: 100%; }

.sheet-classic.div-vertical .sheet-rail,
.sheet-classic.div-both .sheet-rail {
  padding-right: 20px;
  /* The column divider takes the support too, at a lower strength than
     the heading rules so it stays a rule rather than becoming a stripe. */
  border-right: 1px solid color-mix(in srgb, var(--accent) var(--div-mix, 30%), transparent);
}
.sheet-classic.div-vertical.rail-right .sheet-rail,
.sheet-classic.div-both.rail-right .sheet-rail {
  padding: 0 0 0 20px;
  border-right: 0;
  border-left: 1px solid color-mix(in srgb, var(--accent) var(--div-mix, 30%), transparent);
}

/* ---- the rail wash ----
   The one fill that survives. "Panelled" -- the primary solid with the rail
   reversed out of it -- is gone at Rae's call: a reversed block is a
   different design, not a setting of this one, and it was the only state
   here that the delivered Google Doc could not reproduce cell-for-cell.

   The wash stops at the bottom margin rather than bleeding to the paper
   edge, because the document builds it as a shaded cell in a full-height
   row and a cell cannot bleed past the margin. */
.sheet-classic.rail-wash,
.sheet-classic.rail-wash-neutral { display: flex; flex-direction: column; }
.sheet-classic.rail-wash .sheet-body,
.sheet-classic.rail-wash-neutral .sheet-body { flex: 1 1 auto; min-height: 0; }
.sheet-classic.rail-wash .sheet-cols,
.sheet-classic.rail-wash-neutral .sheet-cols { height: 100%; }
.sheet-classic.rail-wash .sheet-rail,
.sheet-classic.rail-wash-neutral .sheet-rail {
  padding: 14px 16px;
  margin: -6px 0 0 -16px;
}
.sheet-classic.rail-wash.rail-right .sheet-rail,
.sheet-classic.rail-wash-neutral.rail-right .sheet-rail {
  margin: -6px -16px 0 0;
}
/* Two washes so the paper and the panel can be mixed rather than locked
   together. The palette wash deepens whatever colour the paper already
   carries; the neutral is a greige that belongs to no palette, so it reads
   as a panel on any of them -- warm enough not to grey out Sand, quiet
   enough not to warm up Soft grey. Both are mixed INTO the paper rather
   than laid over it, so neither fights the stock it sits on. */
/* A pastel sidebar is the most dated thing a resume can carry, and the
   measurement says the fault is CHROMA, not depth. The old panel sat 5-6 L
   below the paper at chroma 3.4: the step was fine, the colour in it was
   what read as a 2015 template.

   Depth is not free to increase either, and the limit is not taste. The
   rail carries the education dates in --meta, and a panel deeper than about
   6 L takes that text under 4.5:1 -- at base #d8d5cf it measures 4.13.
   #e2dfda is the deepest neutral that holds the floor (4.50 exactly).

   So: same step, most of the colour taken out. The palette panel keeps
   enough of the scheme to say which one it is (chroma 0.6-3.8) and stops
   colouring the page in. */
.sheet-classic.rail-wash .sheet-rail {
  background: color-mix(in srgb,
    color-mix(in srgb, var(--tone, var(--accent-2)) 45%, #e2dfda) 90%,
    var(--paper));
}
.sheet-classic.rail-wash-neutral .sheet-rail {
  background: color-mix(in srgb, #e2dfda 90%, var(--paper));
}

/* On the darkest stock a panel cannot sink: the paper is already near the
   panel's value, so the step collapses to 1.5 L and the panel disappears.
   There it LIFTS instead, out of the palette's lighter tint. A panel is a
   change of value; which direction it goes is the paper's business. */
.sheet-classic.paper-tone.rail-wash .sheet-rail,
.sheet-classic.paper-tone.rail-wash-neutral .sheet-rail {
  background: color-mix(in srgb, var(--tertiary, #f4f3f1) 88%, var(--paper));
}

/* ---- name setting ----
   Letter-spaced caps read as engraved rather than typed. It costs width, so
   it is an option rather than the default: a long name at this tracking
   would wrap, and a wrapped name looks like a mistake. */
/* Engraved. It was 31px against a 34px normal setting, so choosing it made
   the name SMALLER -- the opposite of what an engraved setting is for. It
   now sits just under the full 58.7px, which is as large as the letter
   spacing allows before the surname runs into the mark beside it. */
.sheet-classic.name-spaced .sheet-name {
  letter-spacing: 0.1em;
  font-size: calc(50px * var(--fit, 1));
  font-weight: 500;
}
.sheet-classic.name-spaced .sheet-name .given { opacity: 0.55; }

/* Rail side. Source order stays rail-then-main — that is the sensible
   reading order with CSS off, and it is the order the delivered document
   uses — so the swap is visual only. */
/* The mirror of the left-hand split, and it has to be stated as the same
   fraction rather than eyeballed: 0.52fr against 1fr is 34% of the row,
   which quietly took 3% off the main column and wrapped four bullets in
   every right-rail combination. 0.45fr both ways is 31% both ways. */
.sheet-classic.rail-right .sheet-cols { grid-template-columns: 1fr var(--rail-w, 0.45fr); }
.sheet-classic.rail-right .sheet-rail { order: 2; }
.sheet-classic.rail-right .sheet-main { order: 1; }
/* Clear Cut carries its initials in the top-RIGHT corner. Its name sits
   left, so the two balance across the head. Absolutely positioned, so it
   takes no space from the column beneath; and no ring, because a script
   face wants air around it rather than a circle drawn round it. */
.sheet-clearcut .sheet-badge-mono {
  position: absolute;
  top: 34px;
  right: 56px;
  width: auto;
  height: auto;
  margin: 0;
  border: 0;
  background: none;
  display: block;
}
.sheet-clearcut .sheet-badge-mono span {
  /* Great Vibes' capital R carries a swash that curls back over the bowl
     and reads as a K. Parisienne keeps the formality with an unambiguous
     R, which is the whole job of a monogram. */
  font-family: "Parisienne", "Dancing Script", cursive;
  /* 54px is Modern's DEFAULT. As a flat value it swallowed --mono-size,
     so the client's size control did nothing on this layout. */
  font-size: var(--mono-size, 54px);
  font-weight: 400;
  letter-spacing: 0;
  /* A script face carries its ascenders well above the em box, so a
     line-height of 1 clips the capitals against the top of the page. */
  line-height: 1.5;
  display: block;
}

/* ---- Editorial -------------------------------------------
   Warm paper, an accent bar across the top edge, name set right. */
.sheet-editorial { --paper: #faf8f5; border-top: 7px solid var(--accent); padding-top: 38px; }
.sheet-editorial .sheet-head { text-align: right; border-bottom: 1px solid var(--hair); padding-bottom: 10px; }
.sheet-editorial .sheet-cols { grid-template-columns: var(--rail-w, 0.5fr) 1fr; }
.sheet-editorial .sheet-rail { border-right: 1px solid var(--hair); padding-right: 20px; }

/* ---- Executive ------------------------------------------
   A full-width band with the name reversed out of it. Experience
   takes the wide column, everything else a narrow right rail. */
.sheet-executive { padding: 0 0 44px; }
.sheet-executive .sheet-head {
  background: var(--accent-ink);
  color: #fff;
  padding: 30px 52px 24px;
  text-align: center;
}
.sheet-executive .sheet-name { color: #fff; }
.sheet-executive .sheet-name .given { color: #fff; opacity: 0.82; }
.sheet-executive .sheet-role,
.sheet-executive .sheet-contact { color: rgba(255, 255, 255, 0.85); }
.sheet-executive .sheet-body { padding: 0 52px; margin-top: 20px; }
.sheet-executive .sheet-cols { grid-template-columns: 1fr var(--rail-w, 0.46fr); }
.sheet-executive .sheet-rail { order: 2; }
.sheet-executive .sheet-main { order: 1; }
.sheet-executive h3 { text-align: center; }

/* ---- Clear Cut ------------------------------------------
   No rail at all: one column, a large typographic name, and air. */
.sheet-clearcut { padding: 48px 66px; font-size: calc(12.9px * var(--fit, 1) * var(--tidy, 1)); }
.sheet-clearcut .sheet-head { border-bottom: 1px solid var(--hair); padding-bottom: 14px; }
.sheet-clearcut .sheet-name { font-size: 42px; letter-spacing: -0.4px; }
.sheet-clearcut .sheet-cols { grid-template-columns: 1fr; }
.sheet-clearcut .sheet-sec + .sheet-sec { margin-top: 1.32em; }
.sheet-clearcut .sheet-inline { color: var(--muted); }
.sheet-clearcut .sheet-edu { display: inline-block; margin-right: 34px; vertical-align: top; }

/* ---- Profile -------------------------------------------
   A large portrait centred above the name. The most direct way to
   put a face first without rearranging anything else. */
.sheet-profile { padding: 34px 54px; font-size: calc(12.4px * var(--fit, 1) * var(--tidy, 1)); }
.sheet-profile .sheet-head { text-align: center; border-bottom: 1px solid var(--hair); padding-bottom: 14px; }
.sheet-profile .sheet-cols { grid-template-columns: var(--rail-w, 0.46fr) 1fr; }

/* ---- Emblem ------------------------------------------
   Photo set into a full-width accent band beside the name, like
   the top of a business card. */
.sheet-emblem { padding: 0 0 40px; font-size: calc(12.8px * var(--fit, 1) * var(--tidy, 1)); }
.sheet-emblem .sheet-head {
  background: var(--accent-ink);
  color: #fff;
  padding: 26px 48px;
  display: flex;
  align-items: center;
  gap: 26px;
  text-align: left;
}
.sheet-emblem .sheet-name,
.sheet-emblem .sheet-name .given { color: #fff; }
.sheet-emblem .sheet-name .given { opacity: 0.78; }
.sheet-emblem .sheet-role,
.sheet-emblem .sheet-contact { color: rgba(255, 255, 255, 0.86); }
.sheet-emblem .sheet-body { padding: 0 48px; margin-top: 20px; }
.sheet-emblem .sheet-cols { grid-template-columns: var(--rail-w, 0.46fr) 1fr; }

/* ---- Compact --------------------------------------------
   Tighter setting and a narrower rail, so a long career still
   lands on one page. */
.sheet-compact { font-size: calc(12.2px * var(--fit, 1) * var(--tidy, 1)); line-height: 1.38; padding: 38px 46px; }
.sheet-compact .sheet-name { font-size: 33px; }
.sheet-compact .sheet-head { border-bottom: 3px solid var(--accent); padding-bottom: 9px; }
.sheet-compact .sheet-cols { grid-template-columns: 1fr var(--rail-w, 0.42fr); gap: 18px; }
.sheet-compact .sheet-main { order: 1; }
.sheet-compact .sheet-rail { order: 2; border-left: 1px solid var(--hair); padding-left: 16px; }
.sheet-compact .sheet-sec + .sheet-sec { margin-top: 0.9em; }
.sheet-compact .sheet-job + .sheet-job { margin-top: 0.65em; }
.sheet-compact li { margin-bottom: 0.12em; }

/* ============================================================
   Options
   ============================================================
   Each of these is a modifier that applies to every layout, which
   is why there is no "with a photo" design in the set. They are
   what a visitor toggles on the detail page.
   ------------------------------------------------------------ */

/* ---- photo / monogram ----
   A portrait or a monogram sits BESIDE the name, never under it, and both
   can be on at once. Stacked, a badge cost about 110px of a 1056px sheet and
   pushed the body down far enough that two layouts had to refuse a photo
   outright. As a row it costs nothing vertical, and it is where a letterhead
   has always put a mark.

   `head-aside`    one badge  — name, then the badge
   `head-flanked`  two badges — portrait, name, monogram

   Only these two states touch the head, so a layout showing neither keeps
   exactly the head it had. */
/* The name and the mark split the head between them, always. The text
   block takes the slack and the badge sits hard against the far edge, so
   the two halves of the head are the two halves of the page -- never a
   name with a mark tucked under its elbow. */
.sheet.head-aside .sheet-head {
  display: flex;
  /* Baseline, not box centre. The text block is name + role + contact and
     its visual weight sits high; a mark centred against the whole block
     therefore reads low against the name it belongs to. Aligning the two
     boxes' centres is what a flexbox does and it is not what the eye does. */
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.sheet.head-aside .sheet-headtext { flex: 1 1 auto; min-width: 0; }
/* Back into flow. Clear Cut pinned its monogram to the corner with
   `position: absolute; right: 56px` -- which is outside the 66px measure,
   and which takes the mark out of the row entirely, so it neither split the
   head with the name nor responded to being resized. Any layout that pins
   its mark is overruled while a mark is in the head. */
.sheet.head-aside .sheet-badge {
  flex: 0 0 auto;
  margin: 0;
  position: static;
  top: auto; right: auto; bottom: auto; left: auto;
}

/* THE MONOGRAM LINES UP WITH THE NAME, NOT WITH THE BLOCK.
   The rule above says exactly this -- "a mark centred against the whole
   block reads low against the name it belongs to" -- and then centres it
   against the whole block anyway, because that is what align-items does.
   And the two nudges that used to correct it were dead: the margin:0 three
   lines up overrides them both, same specificity, later in the file.
   Measured: the monogram's box came out 92px tall sitting beside a 60px
   name, centred on a 119px stack, so it floated level with the ROLE.

   So it is pinned to the top of the head. HOW FAR IT IS THEN PULLED UP IS
   MEASURED, NOT CALCULATED HERE: the arithmetic that used to live on this
   rule needed the name's height, hard-coded it as 39.52px, and was therefore
   right on the five layouts whose name is 40px and out by 12px on Classic
   and 8px on Academic. The name's height depends on the layout, the face the
   client picked and the --fit step the page solver landed on, so
   alignMonogram() in js/resume-preview.js reads it after layout and writes
   the margin. --mono-fix is its channel; the fallback keeps the mark from
   jumping if the script has not run. */
.sheet.head-aside .sheet-badge-mono {
  align-self: flex-start;
  /* MEASURED, NOT CALCULATED HERE. alignMonogram() in
     js/resume-preview.js reads the mark's rendered strokes and the name's
     and writes --mono-fix. Three things in that sum are unknowable to a
     stylesheet: the ink height of whichever script face the client chose
     (Qwitcher Grypen renders 1.11 of its declared size, Parisienne 1.35),
     the badge's own box on each layout (91px on Classic, 104px on Academic,
     124px on Modern for the same mark), and the name's height, which moves
     with the layout, the face and every --fit step.

     This was tried as CSS arithmetic over a published --name-h and a 0.82
     constant. The 0.82 turned out to be each face's LINE-HEIGHT ratio rather
     than its ink, so the sum centred the badge's line box: right on Classic
     to 1px, 12px low on Academic, 8px high on Modern. */
  margin-top: var(--mono-fix, 0px);
}
/* Source order is name-then-mark. Aligning the name right swaps them
   visually so the two never end up on the same side. */
.sheet.head-aside.head-right .sheet-headtext { order: 2; }
.sheet.head-aside.head-right .sheet-badge { order: 1; }

/* 152px, read off the document: Classic 2 draws its portrait at
   1.78 x 1.71in, which is 171 x 164px at 96dpi, inside an ellipse with a
   1.5pt ring in the palette colour. 92px was mine and it read as an
   avatar rather than as a photograph. */
/* MOVED, NOT RE-LAID-OUT. --badge-dx/--badge-dy are the client's own
   position for the mark (the Move across / Move down sliders, and dragging
   it on the page). A transform rather than margins on purpose: the name and
   the contact line must not shift when somebody nudges their photograph.
   Both scale with --fit, so a move survives the page solver resizing the
   document under it. */
.sheet-badge {
  transform: translate(calc(var(--badge-dx, 0px) * var(--fit, 1)),
                       calc(var(--badge-dy, 0px) * var(--fit, 1)));
  width: 152px; height: 152px;
  border-radius: 50%;
  overflow: hidden;
  margin: 0 auto 14px;
  background: color-mix(in srgb, var(--accent) 10%, #fff);
  box-shadow: 0 0 0 2px var(--accent);
  flex: none;
}
.sheet-badge img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* DRAGGABLE, AND IT SAYS SO. touch-action none so a drag on a phone moves the
   mark instead of scrolling the page out from under it. */
.sheetwrap.live .sheet-badge { cursor: grab; touch-action: none; }
.sheetwrap.live .sheet-badge:active { cursor: grabbing; }
.sheetwrap.live .sheet-badge img { pointer-events: none; }

/* 152px is the size Rae's document draws, and it is right on the layouts
   with an open head. It is not a constant: Charter's head sits inside a
   frame with 30px of padding above it, and a 152px mark there runs 21px off
   the page even at the smallest fit step -- measured, repeatable, across
   every palette and paper. Clear Cut scrapes in at 4px and is one longer
   line away from the same problem.

   So the mark is sized to the head that holds it rather than refused by it.
   Shrinking two layouts is a smaller loss than the alternative, which is
   telling a client they cannot have a photograph on the design they chose. */
.sheet-charter .sheet-badge { width: 104px; height: 104px; }
/* 88px is Academic's DEFAULT MARK SIZE, declared as the property so the
   client's size control -- which writes --mono-size inline on this same
   element, and therefore outranks this -- can move it. As a font-size it
   swallowed the property and the control did nothing here. */
/* 88px is Academic's default mark size, declared as the property so the
   client's control -- which writes --mono-size inline on this same
   element, and so outranks this -- can move it. */
.sheet-charter .sheet-badge-mono { min-width: 120px; --mono-size: 88px; }
.sheet-clearcut .sheet-badge { width: 124px; height: 124px; }
/* Clear Cut's margin is 66px against Classic's 38, so the same mark has
   less room, and the script's closing flourish put it 10px over its own
   text column -- inside the sheet, outside the measure. */
/* 94px is Modern's default, for the same reason. */
.sheet-clearcut .sheet-badge-mono { min-width: 126px; }

/* ---- the monogram ----
   This is Rae's, taken off Classic 3, and the one it replaces was entirely
   mine: a 92px circle with a 2px rule and the initials set in the display
   face. Hers is `A.R.` in QWITCHER GRYPEN at 72pt in the palette colour,
   inside a plain 2.5 x 1.23in text box with no fill and no border. A script
   signature, not a badge.

   Two things follow from that. It gets no circle, no ring and no ground --
   an enclosure is the part that made it look like an avatar. And the face
   has to reach every renderer: it is in none of the fonts a visitor can
   pick, so nothing else would have loaded it, and a missing script face
   falls back to a serif that still looks like a plausible monogram. */
.sheet-badge-mono {
  width: auto; height: auto;
  min-width: 150px;
  border-radius: 0;
  overflow: visible;
  background: none;
  box-shadow: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.sheet-badge-mono span {
  /* --mono-face / --mono-size / --mono-ink are the client's; each falls
     back to exactly what this rule did before they existed, so a sheet
     that sets none of them is byte-identical to the old one. */
  font-family: var(--mono-face, "Qwitcher Grypen"), "Dancing Script", cursive;
  /* 130px was a shade loud beside the name. A script face is judged by the
     weight of its stroke against the roman it sits with, not by its point
     size, so this is set by eye against a 58.7px name and then held. */
  font-size: calc(var(--mono-size, 112px) * var(--fit, 1));
  font-weight: 700;
  letter-spacing: 0;
  color: var(--mono-ink, var(--accent-ink));
  line-height: 0.82;        /* a script face carries its own shoulder */
  white-space: nowrap;
}
/* With no rail, the badge sits in the head instead and aligns with it. */
.sheet-clearcut .sheet-badge { margin: 0 0 14px; }

/* Emblem reverses its head out of the accent, and the badge lands inside
   that band. Left alone the monogram inherits --accent-ink for its ink AND
   sits on --accent-ink as its ground, so the initials are drawn in the band
   colour on the band: invisible, with nothing in the markup to suggest it.
   Anything in a reversed band reverses with it. */
.sheet-emblem .sheet-head .sheet-badge-mono {
  border-color: rgba(255, 255, 255, 0.55);
  background: rgba(255, 255, 255, 0.1);
}
.sheet-emblem .sheet-head .sheet-badge-mono span { color: #fff; }

/* A large centred circle. */
.sheet-badge.photo-round-lg { width: 118px; height: 118px; border: 3px solid var(--accent); margin-bottom: 10px; }

/* A square crop for the masthead band, where a circle would fight the
   straight edges around it. */
.sheet-badge.photo-square {
  width: 96px; height: 96px;
  border-radius: 6px;
  margin: 0;
  border: 2px solid rgba(255, 255, 255, 0.55);
}
.sheet-emblem .sheet-headtext { flex: 1 1 auto; min-width: 0; }


/* ---- paper ----
   The accent tint is mixed rather than fixed, so it follows whatever
   colour the visitor picked instead of fighting it. */
/* `tint` and `tone` arrive as a resolved --paper from the renderer, which
   is why there is no rule for them here: a palette names its own light
   values, so there is nothing left to mix. */

/* ---- dividers ----
   Removing the rules is a real design choice, not an absence: the
   headings keep their weight and the sections breathe further apart
   so the page does not read as unfinished. */
.sheet.no-dividers h3 { border-bottom: 0; padding-bottom: 0; }
.sheet.no-dividers .sheet-sec + .sheet-sec { margin-top: 1.36em; }
.sheet.no-dividers .sheet-head { border-bottom: 0; }
.sheet-editorial.no-dividers .sheet-rail { border-right: 0; }
.sheet-compact.no-dividers .sheet-head { border-bottom: 0; }

/* ---- achievement icons ----
   Marks the two or three bullets worth reading first. A filled star
   at this size reads as emphasis without becoming decoration. */
/* ---- statistical emphasis ----
   Soft, not loud. The figures in a bullet are the evidence in it, so they
   take a half-step up in weight and nothing else: no colour, no italic, no
   marker in the margin. A resume that shouts at six places on the page has
   emphasised nothing.

   600 where the family has it. Lato has no 600 — its cuts jump 400 to 700 —
   so Lato resolves to 700, which is heavier than intended but still reads as
   emphasis rather than as a different voice. Every other body face here has
   a true semibold. */
.sheet.has-stats .sheet-stat { font-weight: 600; }

/* Off by default, and inert rather than absent: the marks are always in the
   markup so toggling the option is a repaint, and so a client who turns it
   off does not silently get different text. */
.sheet-stat { font-weight: inherit; }

/* ---- Charter ------------------------------------------------
   A double-ruled frame with the side panel built into it as a
   compartment rather than floating inside it: the panel's left and
   bottom edges ARE the frame, its top is the header rule, and only
   its right edge is drawn. Every boundary is shared.

   Two colours rather than one. The frame, panel and panel edge take
   --accent, so the layout recolours with everything else; the
   subtitle, headings and ornament stay a fixed antique gold, which
   is metallic enough to sit with all five accents and is what gives
   this layout its character. */
.sheet-charter {
  /* ANTIQUE GOLD, DARKENED TO CARRY TEXT. It was #8a6d3b, which measured
     3.60:1 on the darkest rail this layout can produce and 4.31 on the
     lightest -- so Charter's six rail headings ("Contacts", "Skills",
     "Education"...) failed 4.5:1 on EVERY combination of accent, paper
     and register, not merely some. 176 failures across a 15,144-element
     sweep, and every one of them was this token.

     Solved numerically against the darkest rail the layout can reach
     (#dededd: near-black accent, grey paper), holding hue and chroma in
     OKLCh and lowering only L, 0.552 -> 0.483. Chroma is unchanged to
     four places and the hue moves by one degree, so it is the same
     antique gold and still "metallic enough to sit with all five
     accents" -- it is simply dark enough to read now. 4.83 on the
     darkest rail, 5.78 on the lightest. */
  --gold: #765927;
  padding: 19px;
  display: flex;
  flex-direction: column;
  font-size: calc(12.6px * var(--fit, 1));
  font-weight: 300;
}
.sheet-charter::before {
  content: "";
  position: absolute;
  inset: 16px;
  border: 3px double var(--accent);
  pointer-events: none;
}
.sheet-charter .sheet-head { text-align: center; padding: 30px 44px 14px; }
.sheet-charter .sheet-name {
  font-weight: 500;
  letter-spacing: 2.5px;
  color: var(--accent-ink);
  font-size: 31px;
}
.sheet-charter .sheet-name .given { color: var(--accent-ink); }
.sheet-charter .sheet-role {
  font-family: var(--font-display);
  color: var(--gold);
  letter-spacing: 3.4px;
  text-transform: uppercase;
  font-size: 13px;
}
/* The contact line lives in the panel on this layout, so the head
   carries the ornament in its place. */
.sheet-charter .sheet-contact {
  color: var(--gold);
  font-size: 0;
  letter-spacing: 0;
  margin-top: 7px;
}
.sheet-charter .sheet-contact::before { content: "\25C6"; font-size: 9px; }
.sheet-charter .sheet-body {
  margin-top: 0;
  flex: 1 1 auto;
  min-height: 0;
  border-top: 1.6px solid var(--accent);
}
.sheet-charter .sheet-cols {
  grid-template-columns: 0.345fr 1fr;
  gap: 0;
  height: 100%;
  align-items: stretch;
}
.sheet-charter .sheet-rail {
  background: color-mix(in srgb, var(--accent) 8%, var(--paper));
  border-right: 2px solid var(--accent);
  padding: 16px 16px 16px 20px;
  /* Charter carries six sections in its rail against everyone else's four,
     so it is the layout with the least slack and the first to break when
     the sample content grows. Adding a twelfth skill and the longer
     "Lean Six Sigma Green Belt | 2020" form put it 30px over with 203px
     still free in the main column. Tightened here rather than by dropping
     a section: the rail's six compartments are the design. */
  font-size: 11.1px;
}
.sheet-charter .sheet-main { padding: 16px 20px 16px 22px; }
.sheet-charter h3 { color: var(--gold); border-bottom: 0; letter-spacing: 2.2px; }
.sheet-charter h3::after {
  content: "";
  display: block;
  width: 100%;
  border-bottom: 1px solid currentColor;
  margin-top: 2px;
}
.sheet-charter .sheet-role-title { color: var(--accent-ink); font-weight: 600; }
.sheet-charter li::before { background: var(--gold); }


/* A link the client's own PDF carried. Underlined rather than coloured:
   the accent is the layout's, and a resume that turns every address into a
   second colour stops looking like a document. It stays a real <a>, so
   print-to-PDF writes it as an annotation and a reader can click it. */
.sheet-link { color: inherit; text-decoration: underline; text-underline-offset: 2px;
              text-decoration-thickness: .5px; text-decoration-color: var(--meta); }

/* =====================================================================
   MULTI-PAGE, AND PRINT
   ===================================================================== */

/* Pages stack with a gap on screen so the breaks are visible -- a client
   needs to see WHERE page two starts, because that is a real decision
   about their resume and not an implementation detail. */
.sheet-pages { display: flex; flex-direction: column; gap: 16px; align-items: flex-start; }

/* A continuation carries no head, so its body starts at the top margin. */
.sheet-cont .sheet-body { margin-top: 0; }
.sheet-cont .sheet-cols { height: 100%; }

/* "Experience (cont)" -- the heading is repeated so page two is not an
   unlabelled list of jobs, and marked so it can be styled quieter than a
   first appearance. */
.sheet-sec h3[data-continued] { opacity: .72; }
.sheet-sec h3[data-continued]::after { content: " (continued)"; font-size: .82em; letter-spacing: .04em; }
.sheet-role-title[data-continued] { opacity: .78; }
.sheet-role-title[data-continued]::after { content: " (continued)"; font-weight: 400; font-size: .86em; }

/* ---------------------------------------------------------------------
   PRINT. The sheet is 816x1056 CSS px, which is exactly 8.5x11in at the
   96dpi CSS reference -- so the page box is declared at that size with no
   margin and the sheet's own padding becomes the margin. Anything else
   double-margins it and the second page starts half an inch lower than
   the first.

   transform:none is not optional: the studio scales the preview to fit
   the viewport, and a scaled sheet prints scaled.
   --------------------------------------------------------------------- */
@media print {
  @page { size: 8.5in 11in; margin: 0; }

  html, body { background: #fff !important; margin: 0 !important; padding: 0 !important; }

  /* Everything that is not the document itself. */
  /* THE TOOLBAR PRINTS TOO IF NOBODY STOPS IT. It replaced .panel, which
     was on this list, and the saved PDF went straight back to three pages
     for a two-page resume -- 52px of toolbar above a document whose height
     is an exact number of sheets. Same shape of bug as the 22px of .studio
     padding before it. Measured: 3 pages with it, 2 without. */
  .tbar, #menus, .menu, .stage-note, .broke,
  .bar, .gallery, .panel, .under, .nav, .footer, .chosen,
  .cta-band, .zoomer, .rs-chip, .cloths, .huestrip, .photochip,
  /* the test harness's own status line: printing it pushed the document
     down and cost a whole extra sheet of paper */
  #log, #status, #out { display: none !important; }

  /* THE CONTAINERS CONTRIBUTE NOTHING. .studio is a 22px-padded grid with
     a 26px gap; with the panel hidden that is 44px of blank above and below
     a document whose height is already an exact number of sheets, and it
     bought a third page on every two-page export. Measured: 3 pages before,
     2 after. */
  .studio, .stage { display: block !important; padding: 0 !important;
                    gap: 0 !important; margin: 0 !important; max-width: none !important; }
  .sheet-pages { display: block; gap: 0; }
  .stage, .sheetwrap, #host, .sheet-pages { transform: none !important;
    width: auto !important; height: auto !important; max-height: none !important;
    overflow: visible !important; }

  .sheet {
    break-after: page; page-break-after: always;
    box-shadow: none !important; border: 0 !important;
    transform: none !important; margin: 0 !important;
    /* the accent is the point of the exercise; browsers drop backgrounds
       and colours in print unless told otherwise */
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .sheet:last-child { break-after: auto; page-break-after: auto; }

  /* A job must not be torn across a page by the PRINT engine either --
     pagination already placed the breaks, and the browser re-breaking them
     is how a role heading ends up alone at the foot of a sheet. */
  .sheet-job, .sheet-sec > li, .sheet-sec > p { break-inside: avoid; page-break-inside: avoid; }
}


/* An imported resume whose sections are all too long for a rail sets as a
   single column across the full measure. Without this the main column
   inherits the rail's grid track and sets at half the width. */
.sheet-onecol .sheet-cols { display: block !important; grid-template-columns: 1fr !important; }
.sheet-onecol .sheet-main { width: auto !important; }


/* A CLIENT'S NAME IS NOT SHOUTED. Some layouts set the sample's name in
   capitals, which is a design choice about a name we invented. Doing it to
   a real person changes how they wrote their own name -- and it is
   measurably harder to read back: the checker's own extractor identified
   the candidate on a printed resume set in title case and failed on the
   same resume set in capitals. Faithfulness and machine-readability point
   the same way here. */
.sheet-imported .sheet-name { text-transform: none; }
