/* ==========================================================================
   RESOURCES — the tabbed library hub at /resources.

   Load it AFTER /css/system.css:

     <link rel="stylesheet" href="/css/system.css">
     <link rel="stylesheet" href="/css/resources.css">

   Tokens, type, buttons, .sec, .cta, the footer and the nav component all come
   from system.css. Nothing here redefines them, and there are no hardcoded
   colour values in this file.

   PROGRESSIVE ENHANCEMENT, and it matters for how this file is written.
   The markup ships with every panel visible and the tab bar [hidden]. Nothing
   is behind a click until /js/tabs.js runs, flips that around, and puts
   `has-tabs` on <html>. So the DEFAULT styles here are the no-JS stacked
   reading order, and the `.has-tabs` rules are the override. Write it the
   other way round and the page is three invisible panels the moment the
   script 404s.
   ========================================================================== */

/* clip, not hidden — overflow:hidden on <body> makes it a scroll container
   and silently kills position:sticky on the header. */
body{overflow-x:clip}

/* ---- HEADER --------------------------------------------------------------
   Flush left. The one centred header on the site is the homepage statement;
   this is a signpost.

   Its own ground, a step DARKER than the page. The library used to run header,
   tabs, panels and closing prose all on one flat --ox field, which left nothing
   for the eye to use as a landmark — you could not tell by glancing whether
   you had scrolled. Three grounds now: --ox-deep here, --brown across the
   whole tab section, --ox under the closing prose.                           */
/* The band is `.photo-hero .hero-card` now, the shared cream photographic hero
   from system.css, so the ground, the photograph, the scrim, the padding and
   the light palette all come from there. Declare none of them here: this file
   loads after system.css at equal specificity and a `padding` or `background`
   restated below would silently win.

   Gone with the dark version: the --ox-deep fill, the accent hairline along
   the bottom (the card's edge draws that now) and the cowboy watermark. The
   watermark was texture for an empty band; the band has a photograph in it. */
/* hvac-2 is a 4:5 portrait dropped into a wide short band, so cover throws
   away more than half the height and the Y value is the only control that
   matters. 24% puts the window on the technician's head and shoulders; the
   default 46% lands it on his chest. */
.res-top{--hero-pos-w:50% 24%}
.res-top h1{max-width:15ch}
.res-top .lede{max-width:60ch;margin-top:20px}

/* ---- TAB BAR -------------------------------------------------------------
   A rule with an accent underline on the active label, not a row of pills or
   icon cards. Every other index on this site separates things with hairlines;
   a pill row here would be the only capsule UI on the whole build.           */
.tabs-sec{
  background:var(--brown);
  padding:clamp(26px,3vw,38px) 0 clamp(44px,4.2vw,72px);
}
/* This band is the .hero-join under the raised hero card, and it sets its own
   top padding. resources.css loads after system.css and both selectors are
   (0,1,0), so the shorthand above wins and .hero-join's calc is thrown away,
   which puts the tab row hard against the card's rounded corner. Restated here
   at (0,2,0) as the band's own padding PLUS the radius it is pulled up by.
   See "THE RAISED HERO CARD" in system.css. */
.tabs-sec.hero-join{
  padding-top:calc(clamp(26px,3vw,38px) + clamp(20px,2.6vw,38px));
}

.tabbar{
  display:flex;flex-wrap:wrap;align-items:flex-end;
  gap:clamp(16px,3vw,46px);
  border-bottom:1px solid var(--line);
}
/* [hidden] on a flex container needs saying out loud — display:flex would
   otherwise win and the bar shows up for the no-JS reader it is hidden for. */
.tabbar[hidden]{display:none}

.tab{
  appearance:none;background:none;border:0;border-bottom:2px solid transparent;
  margin-bottom:-1px;padding:0 0 14px;cursor:pointer;
  display:inline-flex;align-items:baseline;gap:8px;
  font-family:inherit;font-weight:800;line-height:1.2;
  font-size:clamp(12.5px,1.25vw,14.5px);letter-spacing:.14em;text-transform:uppercase;
  color:var(--sand-2);
  transition:color .2s var(--ease),border-color .2s var(--ease);
}
.tab:hover{color:var(--sand)}
.tab[aria-selected="true"]{color:var(--accent);border-bottom-color:var(--accent)}

/* Item count. Tabular figures so the labels don't shuffle sideways by a pixel
   when a count goes from 3 to 10. */
.tab-n{
  font-size:11px;font-weight:700;letter-spacing:.1em;color:var(--sand-3);
  font-variant-numeric:tabular-nums;
}
.tab[aria-selected="true"] .tab-n{color:var(--accent)}

/* Under ~640px the three labels no longer fit on one line. Wrapped, the active
   tab's underline sits on row one while the bar's own rule sits under row two,
   and the two lines read as unrelated. So below that the bar stops being a bar
   and becomes three full-width rows with a rule under each — the accent rule
   stays attached to its own label, and nothing has to scroll sideways. */
@media (max-width:660px){
  .tabbar{
    display:grid;grid-template-columns:1fr;gap:0;
    border-bottom:0;border-top:1px solid var(--line);
  }
  .tab{
    width:100%;justify-content:space-between;align-items:center;
    margin:0;padding:13px 0;
    border-bottom:1px solid var(--line);
  }
  .tab[aria-selected="true"]{border-bottom-color:var(--accent)}
}

/* ---- PANELS --------------------------------------------------------------
   With no JS the three panels stack and a rule separates them. With JS only
   one is on screen at a time, so that rule is just a line under the tab bar
   drawn twice.                                                               */
.panel{padding-top:clamp(28px,3.2vw,44px)}
.panel + .panel{margin-top:clamp(34px,4vw,54px);border-top:1px solid var(--line)}
.has-tabs .panel + .panel{margin-top:0;border-top:0}

.panel-head{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:12px 30px}
.panel-head h2{margin:0;max-width:22ch;font-size:clamp(24px,2.5vw,32px)}
.panel-lede{margin:14px 0 0;max-width:62ch;color:var(--sand-2);font-size:15.5px;line-height:1.6}
.panel-all{flex:0 0 auto;font-weight:700;font-size:13.5px;white-space:nowrap}

/* ---- ARTICLE CARDS -------------------------------------------------------
   Filled panels, not hairline frames. On the --brown slab an outlined card is
   four thin lines and nothing else, which is exactly what made this page read
   as flat. Each card now gets a panel a step lighter than the slab, a top-lit
   gradient, a 1px inset highlight and a shadow deep enough to separate the
   corners — the same four-at-once treatment the homepage reviews use, because
   any one of them alone on a dark ground just reads as a different brown.    */
.res-cards{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.8vw,22px);margin-top:clamp(22px,2.6vw,32px);
}
@media (max-width:860px){.res-cards{grid-template-columns:1fr;max-width:560px}}

.res-card{
  display:flex;flex-direction:column;
  padding:clamp(20px,2.2vw,26px);
  text-decoration:none;color:inherit;
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--ox-2) 88%,var(--sand)) 0%,
    var(--ox-2) 64%);
  border:1px solid color-mix(in srgb,var(--sand) 18%,transparent);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb,var(--sand) 20%,transparent),
    0 18px 40px -24px var(--ox-deep);
  transition:border-color .3s var(--ease),transform .3s var(--ease),box-shadow .3s var(--ease);
}
.res-card:hover{
  border-color:color-mix(in srgb,var(--accent) 60%,transparent);
  transform:translateY(-3px);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb,var(--sand) 28%,transparent),
    0 26px 50px -22px var(--ox-deep);
}
@media (prefers-reduced-motion:reduce){.res-card,.res-card:hover{transform:none;transition:none}}

/* The format word is a chip rather than another line of small caps. It is the
   one piece of colour that survives a squint at the card grid, which is what
   tells you at a glance that these three are the same kind of thing. */
.res-meta{
  display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-bottom:15px;
  font-weight:700;font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--sand-3);
}
.res-meta b{
  padding:4px 9px;font-weight:800;letter-spacing:.14em;
  color:var(--accent);
  background:color-mix(in srgb,var(--accent) 16%,transparent);
  border:1px solid color-mix(in srgb,var(--accent) 38%,transparent);
}
.res-card h3{font-size:clamp(17px,1.6vw,20px);line-height:1.25;margin-bottom:.5em}
.res-card p{margin:0;flex:1;font-size:14.5px;line-height:1.55;color:var(--sand-2)}
.res-card .go{
  margin-top:20px;padding-top:15px;
  border-top:1px solid color-mix(in srgb,var(--sand) 14%,transparent);
  color:var(--accent);font-weight:700;font-size:13px;letter-spacing:.03em;
}

/* ---- SHELVES -------------------------------------------------------------
   The two topic shelves, kept as full-width linked rows rather than folded
   into the card grid above. They are not articles — they are folders that
   hold articles — and sizing them like an article says the wrong thing.      */
.shelf-lede-label{
  display:block;margin:clamp(34px,4vw,50px) 0 clamp(14px,1.6vw,20px);
  padding-top:clamp(20px,2.2vw,28px);border-top:1px solid var(--line);
}
/* The shelves sit in one bordered, tinted block rather than floating as two
   loose rows under the cards. That box is the thing that makes "By topic"
   read as a second, different kind of list instead of more article rows —
   and it is a container, so the rule between the two shelves is internal and
   the last one has none. */
.shelves{
  border:1px solid color-mix(in srgb,var(--sand) 15%,transparent);
  background:color-mix(in srgb,var(--ox-2) 55%,transparent);
  padding-inline:clamp(18px,2.2vw,30px);
}

.shelf{
  display:grid;grid-template-columns:minmax(0,.95fr) minmax(0,1.15fr);
  gap:clamp(16px,3.2vw,52px);
  padding:clamp(20px,2.4vw,30px) 0;border-bottom:1px solid var(--line);
  text-decoration:none;color:inherit;
}
.shelf:last-child{border-bottom:0}
.shelf:hover h3{color:var(--accent)}
.shelf h3{transition:color .2s var(--ease)}
@media (max-width:820px){.shelf{grid-template-columns:1fr;gap:20px}}

.shelf h3{font-size:clamp(20px,2.2vw,27px);margin-bottom:.4em}
.shelf-lede{color:var(--sand-2);max-width:42ch;margin:0;font-size:15.5px;line-height:1.58}

/* The arrow is the affordance — the whole row is the hit area, so there is no
   separate button to hover. */
.shelf-go{
  display:inline-flex;align-items:center;gap:9px;margin-top:17px;
  color:var(--accent);font-weight:700;font-size:13px;letter-spacing:.03em;
}
.shelf-go::after{
  content:"";width:7px;height:7px;flex:0 0 auto;
  border-top:1.5px solid currentColor;border-right:1.5px solid currentColor;
  transform:rotate(45deg);transition:transform .3s var(--ease);
}
.shelf:hover .shelf-go::after,
.shelf:focus-visible .shelf-go::after{transform:rotate(45deg) translate(3px,-3px)}

/* Sample topics. Not links — nothing to link to yet — so they must not look
   clickable. */
.shelf-topics{margin:0;padding:0;list-style:none;display:grid;align-content:start}
.shelf-topics li{
  padding:10px 0;border-top:1px solid var(--line);
  color:var(--sand-2);font-size:15px;line-height:1.5;
}
.shelf-topics li:first-child{border-top:0;padding-top:0}
@media (max-width:820px){.shelf-topics li:first-child{border-top:1px solid var(--line);padding-top:10px}}
/* Descendant selector, not a bare class — `.shelf-topics li` above is (0,1,1)
   and would otherwise win the colour and size back off .label. */
.shelf-topics .shelf-count{
  font-size:11px;letter-spacing:.2em;text-transform:uppercase;font-weight:700;
  color:var(--sand-3);padding-top:15px;
}

/* ---- SLOTS ---------------------------------------------------------------
   Nothing is published in Courses or Content yet. These are dashed frames
   that say so in words rather than greyed-out cards you can click into
   nothing. Strip `is-slot` and swap the <div> for an <a> when the real thing
   exists; the card metrics already fit.                                      */
.slots{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(14px,1.8vw,22px);margin-top:clamp(22px,2.6vw,32px);
}
@media (max-width:860px){.slots{grid-template-columns:1fr;max-width:560px}}

/* Dashed frame AND a faint fill. Dashes alone on a dark slab are four grey
   lines around nothing, which is the definition of flat; the fill gives the
   slot a body so the grid still has three objects in it, just unfinished
   ones. */
.slot{
  display:flex;flex-direction:column;
  padding:clamp(20px,2.2vw,26px);
  border:1px dashed color-mix(in srgb,var(--sand) 26%,transparent);
  background:color-mix(in srgb,var(--ox-2) 42%,transparent);
}
.slot h3{font-size:clamp(16.5px,1.5vw,19px);line-height:1.25;margin-bottom:.5em}
.slot p{margin:0;flex:1;font-size:14.5px;line-height:1.55;color:var(--sand-2)}
.slot .label{display:block;margin-bottom:12px}

/* ---- PAGE HERO -----------------------------------------------------------
   Header for /content ONLY now. /work and /courses used to share it and have
   moved to .photo-hero, the shared cream photographic hero in system.css, with
   every other top-of-page band on the site. /resources moved there too.

   /content did not, and the reason is the paragraph below: this is the one
   page whose hero is deliberately not a picture. Do not "finish the job" by
   converting it without asking — the channel-art header is recent and it is
   the way it is on purpose.

   Contour ground rather than a photograph. On /content the thumbnails
   underneath are already three competing pictures, so a fourth image up here
   was one more thing to look at before the videos; the topo gives the band
   depth without asking for any attention.

   Contrast is a property of the ground instead of a property of the crop, so
   the copy can sit anywhere in the band and there is no scrim to tune.

   The bottom edge dissolves into --brown, which is the ground of the video
   strip directly below (.sec.slab), so the header and the videos read as one
   block instead of a panel with a list parked under it.                     */
.page-hero{
  position:relative;isolation:isolate;overflow:hidden;
  /* The radial is off-centre and warm so the band is lit from the top left
     and reads as a surface. Flat --ox-deep alone reads as a gap in the page. */
  background:
    radial-gradient(86% 120% at 14% 0%,
      color-mix(in srgb,var(--accent) 15%,transparent),
      transparent 64%),
    linear-gradient(148deg,var(--ox-2),var(--ox-deep));
  padding:clamp(64px,8vw,118px) 0 clamp(78px,8vw,128px);
}
.page-hero::before{
  content:"";position:absolute;z-index:-2;inset:0;pointer-events:none;
  /* Bled past the edges so the cover scale never lands a contour line exactly
     on the seam, where it would read as a border rather than terrain. The
     strokes in the file are already --sand, so no filter is needed here —
     unlike .cta, which inverts them to sit on the one light band. */
  inset:-14% -10%;
  background:url(/assets/topo.svg) center/cover no-repeat;
  opacity:.28;
}
.page-hero::after{
  content:"";position:absolute;z-index:-1;inset:0;pointer-events:none;
  /* Measured in px from the bottom, not percent — a percentage fade climbs
     into the headline as the section grows on a narrow viewport. */
  background:linear-gradient(to top,
    var(--brown) 0px,
    color-mix(in srgb,var(--brown) 55%,transparent) 56px,
    transparent 128px);
}
.page-hero>.wrap{position:relative;z-index:1}
.page-hero h1{max-width:16ch;margin:0}
.page-hero p{
  margin:18px 0 0;max-width:46ch;
  font-size:clamp(15.5px,1.5vw,17px);line-height:1.6;color:var(--sand-2);
}
.page-hero .btn{margin-top:clamp(24px,2.8vw,34px)}

/* The strip owns the seam: the fade above lands on its ground, so a normal
   section gap here would reopen the join the dissolve exists to close. */
.vid-sec{padding-top:clamp(10px,1.4vw,18px)}

/* ---- VIDEOS --------------------------------------------------------------
   One row of thumbnails, nothing around them. No panel, no card fill, no
   border on the group — the stills are already three bright rectangles on a
   dark slab, and a frame around a picture that is doing its own work just
   adds a line to look at. The only chrome is the play disc and the runtime.

   LONG-FORM ONLY. Shorts are deliberately not listed here: they are 9:16, so
   they cannot share this row without being pillarboxed into stamps, and a
   second row for them turns a simple strip into a layout. They are one click
   away on the channel.

   FACADE, NOT AN IFRAME. A YouTube embed is roughly a megabyte of script and
   a set of third-party cookies, per video, on page load — for something most
   visitors never press. What ships is a local still and a play button; the
   iframe is built by /js/video.js on the first click. With no JS the same
   element is a plain link to the video on YouTube, which is the correct
   fallback: worst case the visitor watches it, just not here.

   Thumbnails are stored in /images/video/ rather than hotlinked from
   i.ytimg.com, so the page makes zero requests to Google before a click. They
   do NOT auto-update — re-pull the still when a video's thumbnail changes. */
.vid-row{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(16px,2vw,26px);margin-top:clamp(22px,2.6vw,32px);
}
/* Two-up is skipped on purpose. These are 16:9, so a two-column row makes
   each still huge and the strip stops reading as a list of videos. */
@media (max-width:760px){.vid-row{grid-template-columns:1fr;max-width:460px}}

/* ---- VIDEO FACADE -------------------------------------------------------
   .vid-thumb / .vid-play / .vid-len and the .vid hover states moved to
   /css/system.css on 2026-10-09, so the homepage VSL could use them without
   loading this whole sheet. Nothing about them changed in the move beyond
   some em-dashes in the comments. Edit them there, never copy them back.

   .vid-row above stays here: it is the 3-up grid for this page, not part of
   the card. /js/video.js is what upgrades any .vid-thumb[data-yt] to a real
   player, and it is unchanged.                                              */
/* ---- CHANNEL ROW ---------------------------------------------------------
   One framed row for the channel itself, above the videos, so the page opens
   with somewhere to actually go.                                             */
.channel{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:18px clamp(20px,3vw,44px);
  margin-top:clamp(22px,2.6vw,32px);padding:clamp(20px,2.4vw,30px);
  border:1px solid color-mix(in srgb,var(--accent) 38%,transparent);
  background:
    radial-gradient(130% 120% at 0% 0%,color-mix(in srgb,var(--accent) 9%,transparent),transparent 62%),
    var(--ox-2);
}
.channel h3{margin-bottom:.4em;font-size:clamp(19px,1.9vw,23px)}
.channel p{margin:0;max-width:52ch;font-size:15px;line-height:1.58;color:var(--sand-2)}
.channel .btn{flex:0 0 auto}

/* ---- FOOT NOTE -----------------------------------------------------------
   One plain sentence under a panel, for the things that aren't built. Said
   outright beats a shelf you can click that goes nowhere.                    */
.panel-note{margin-top:clamp(22px,2.6vw,32px);max-width:62ch;font-style:italic;color:var(--sand-2)}

/* ---- HOW THIS LIBRARY WORKS ----------------------------------------------
   Two columns of plain prose. No cards, no icons.                            */
/* No background: the tab section above is the --brown slab now, so this sits
   back on the page ground. Two brown bands in a row would undo the whole
   point of giving the library its own field. */
.stance-g{display:grid;grid-template-columns:1fr;gap:clamp(22px,3vw,48px);margin-top:clamp(26px,3vw,38px)}
@media (min-width:760px){.stance-g{grid-template-columns:1fr 1fr}}
.stance h3{font-size:clamp(18px,1.8vw,21px)}
.stance p{max-width:52ch}
