/* ===========================================================================
   Illustration: the shelf (Chapter III, The Playbook; theme "blue").
   Every book Stuart wrote or co-wrote and every foreword he wrote, as spines
   on a shelf in year order, plus a small diagram of how a Hacking Exposed
   chapter teaches (the attack, then the countermeasure).

   Markup is generated by build.py from assets/data/library.js. Two drawings
   of the same shelf: one long shelf (figure >= 860px wide) and three short
   shelves (narrower). Container queries pick one, so the labels never render
   below 12px. Spines are drawn once (in .il-shelf-defs) and placed with <use>.

   Motion (one-shot, on .is-in from site.js): the spines slide onto the shelf
   in year order while the year counter above counts 1999 -> 2026; then the
   chapter diagram's arrow draws across the gutter and the brass stripe swings
   level. Without JS or with reduced motion the drawing is complete and static.
   =========================================================================== */

.illus--shelf { margin: 0; container: il-shelf / inline-size; }

/* ---- Year counter: a registered integer, so it can animate as a number */
@property --il-shelf-y { syntax: "<integer>"; inherits: true; initial-value: 2026; }
.il-shelf-top { display: flex; align-items: baseline; justify-content: flex-end; gap: .7rem; margin: 0 0 .4rem; }
.il-shelf-kicker { font-size: .95rem; color: var(--muted); }
.il-shelf-year { --il-shelf-y: 2026; counter-reset: il-shelf-y var(--il-shelf-y);
  font-family: var(--serif); font-style: italic; font-weight: 300; font-size: clamp(2.4rem, 1.7rem + 2vw, 3.4rem); line-height: 1;
  color: var(--accent); font-variant-numeric: tabular-nums lining-nums; min-width: 2.3em; text-align: right; }
.il-shelf-year::before { content: counter(il-shelf-y); }

/* ---- The two drawings of the shelf */
.il-shelf-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.il-shelf-svg { display: block; width: 100%; height: auto; overflow: visible; }
.il-shelf-svg--wide { display: none; }
.il-shelf-svg--narrow { max-width: 460px; margin-inline: auto; }
@container il-shelf (min-width: 860px) {
  .il-shelf-svg--wide { display: block; }
  .il-shelf-svg--narrow { display: none; }
}

/* Spines. The Hacking Exposed family: black with brass bands and brass years.
   The Windows volumes add a steel-blue band. Web Hacking is cream, so it is easy to find.
   Forewords are slimmer, in a quieter slate, set apart behind their own bookend. */
.il-shelf-body { stroke: rgba(255,255,255,.12); stroke-width: 1; }
.il-shelf-sp--he .il-shelf-body, .il-shelf-sp--hew .il-shelf-body { fill: url(#il-shelf-g-he); }
.il-shelf-sp--web .il-shelf-body { fill: url(#il-shelf-g-web); }
.il-shelf-sp--guard .il-shelf-body { fill: url(#il-shelf-g-guard); }
.il-shelf-sp--fw .il-shelf-body { fill: url(#il-shelf-g-fw); }
.il-shelf-sp--web .il-shelf-body { stroke: rgba(0,0,0,.25); }
.il-shelf-rule { fill: url(#il-shelf-g-brass); }
.il-shelf-sp--web .il-shelf-rule { fill: #7a6247; }
.il-shelf-sp--fw .il-shelf-rule { fill: rgba(238,240,245,.35); }
.il-shelf-cap { fill: #5f7396; }
.il-shelf-sheen { fill: #fff; opacity: .07; }
.il-shelf-sp--web .il-shelf-sheen { opacity: .35; }
.il-shelf-t { font-family: var(--sans); font-size: 17px; font-weight: 600; fill: #eef0f5; dominant-baseline: central; }
.il-shelf-t2 { font-size: 16px; font-weight: 500; fill: rgba(238,240,245,.78); }
.il-shelf-yr { font-family: var(--sans); font-size: 17px; font-weight: 700; text-anchor: middle; fill: #d9c9a6; font-variant-numeric: lining-nums; }
.il-shelf-sp--web .il-shelf-t { fill: #1b1d22; }
.il-shelf-sp--web .il-shelf-t2 { fill: rgba(27,29,34,.78); }
.il-shelf-sp--web .il-shelf-yr { fill: #5e4a33; }
.il-shelf-sp--fw .il-shelf-yr, .il-shelf-sp--guard .il-shelf-yr { fill: #eef0f5; }
/* Phones: the three-shelf drawing renders at ~0.75x at 360px, so the second title line
   (16px) would fall just under 12px on screen. Lift it to 17px when the figure is narrow.
   The spine defs sit inside the figure, so this query restyles every <use> of them. */
@container il-shelf (max-width: 420px) {
  .il-shelf-t2 { font-size: 17px; }
}
.il-shelf-end-sh { fill: rgba(0,0,0,.22); }
.il-shelf-cav { stroke: var(--hair); stroke-width: 1; }

/* ---- How a chapter teaches */
.il-shelf-method { display: grid; gap: clamp(1.4rem, 3vw, 3rem); align-items: center; margin-top: clamp(2.4rem, 5vw, 4rem);
  padding-top: clamp(2rem, 4vw, 3rem); border-top: 1px solid var(--hair); container: il-shelf-m / inline-size; }
@container il-shelf (min-width: 860px) { .il-shelf-method { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
/* Tablets: the three short shelves on the left, the chapter diagram beside them */
@container il-shelf (min-width: 600px) and (max-width: 859.98px) {
  .il-shelf-in { display: grid; grid-template-columns: minmax(0, 440px) minmax(0, 1fr); column-gap: clamp(24px, 4vw, 48px); align-items: start; }
  .il-shelf-top, .il-shelf-svg--narrow { grid-column: 1; }
  .il-shelf-method { grid-column: 2; grid-row: 1 / span 3; align-self: center; margin-top: 0; padding-top: 0; border-top: 0; }
}
.il-shelf-msvg { display: block; width: 100%; max-width: 520px; height: auto; overflow: visible; }
.il-shelf-mcover { fill: #262b36; stroke: rgba(255,255,255,.12); }
.il-shelf-step circle { fill: #5b3f8c; }
.il-shelf-step text { font-family: var(--sans); font-size: 16px; font-weight: 700; fill: #fff; text-anchor: middle; dominant-baseline: central; }
.il-shelf-bar { fill: rgba(20,20,20,.2); }
.il-shelf-stripe { stroke: #e6d6b4; stroke-width: 7; stroke-linecap: round; }
.il-shelf-arrow { fill: none; stroke: url(#il-shelf-g-arrow); stroke-width: 5; stroke-linecap: round; }
.il-shelf-head { fill: #7a6247; }
.il-shelf-mtext { display: grid; gap: 1.4rem; }
.il-shelf-mp { color: var(--muted); font-size: 1.05rem; line-height: 1.65; max-width: 34rem; }
.illus--shelf figcaption { margin-top: 1.6rem; font-size: .9rem; color: var(--muted); max-width: 46rem; }

/* Phones: the diagram scales down, so its labels get larger to stay >= 12px on screen */
@container il-shelf-m (max-width: 420px) {
  .il-shelf-msvg .il-shelf-ml { font-size: 22px; }
  .il-shelf-msvg .il-shelf-ms { font-size: 19px; }
  .il-shelf-msvg .il-shelf-step text { font-size: 19px; }
}
@container il-shelf-m (max-width: 340px) {
  .il-shelf-msvg .il-shelf-ml { font-size: 25px; }
  .il-shelf-msvg .il-shelf-ms { font-size: 22px; }
  .il-shelf-msvg .il-shelf-step text { font-size: 22px; }
}

/* ---- Motion, once */
@media (prefers-reduced-motion: no-preference) {
  .js .illus--shelf .il-shelf-bk { opacity: 0; transform: translate(54px, -12px) rotate(7deg); transform-box: fill-box; transform-origin: 50% 100%;
    transition: opacity 360ms ease-out var(--t, 0ms), transform 720ms var(--ease-out) var(--t, 0ms); }
  .js .illus--shelf.is-in .il-shelf-bk { opacity: 1; transform: none; }
  .js .illus--shelf .il-shelf-grp { opacity: 0; transition: opacity 600ms ease 100ms; }
  .js .illus--shelf.is-in .il-shelf-grp { opacity: 1; }
  .js .illus--shelf .il-shelf-year { --il-shelf-y: 1999; }

  /* The diagram has its own reveal: steps appear, the arrow crosses, the stripe levels */
  .js .il-shelf-method .il-shelf-step { opacity: 0; transform: translateX(-10px); transition: opacity 400ms ease-out, transform 500ms var(--ease-out); transition-delay: calc(250ms + var(--s) * 150ms); }
  .js .il-shelf-method .il-shelf-arrow { stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 800ms var(--ease-out) 800ms; }
  .js .il-shelf-method .il-shelf-head, .js .il-shelf-method .il-shelf-fix { opacity: 0; transition: opacity 400ms ease 1400ms; }
  .js .il-shelf-method .il-shelf-stripe { transform-box: view-box; transform-origin: 362px 182px; transform: rotate(-38deg); transition: transform 900ms var(--ease-out) 1500ms; }
  .js .il-shelf-method.is-in .il-shelf-step { opacity: 1; transform: none; }
  .js .il-shelf-method.is-in .il-shelf-arrow { stroke-dashoffset: 0; }
  .js .il-shelf-method.is-in .il-shelf-head, .js .il-shelf-method.is-in .il-shelf-fix { opacity: 1; }
  .js .il-shelf-method.is-in .il-shelf-stripe { transform: none; }
}

/* BEGIN GENERATED by build.py: do not edit by hand */
@media (prefers-reduced-motion: no-preference) {
  .js .illus--shelf.is-in .il-shelf-year { animation: il-shelf-count 1572ms linear 450ms both; }
}
@keyframes il-shelf-count {
  0.0% { --il-shelf-y: 1999; }
  5.3% { --il-shelf-y: 2000; }
  10.7% { --il-shelf-y: 2001; }
  14.9% { --il-shelf-y: 2001; }
  20.2% { --il-shelf-y: 2002; }
  25.6% { --il-shelf-y: 2003; }
  29.8% { --il-shelf-y: 2003; }
  35.1% { --il-shelf-y: 2004; }
  40.5% { --il-shelf-y: 2005; }
  44.7% { --il-shelf-y: 2005; }
  50.0% { --il-shelf-y: 2006; }
  55.3% { --il-shelf-y: 2007; }
  61.8% { --il-shelf-y: 2009; }
  69.5% { --il-shelf-y: 2012; }
  78.2% { --il-shelf-y: 2016; }
  84.7% { --il-shelf-y: 2018; }
  93.5% { --il-shelf-y: 2024; }
  100.0% { --il-shelf-y: 2026; }
}
/* END GENERATED */
