/* ==========================================================================
   NexusPool blog — Hashfield
   Hand-written, shipped as-is. No build step, which is also why no source map
   can ever leak the platform name or internal paths (that was a real finding
   against the previous theme).
   ========================================================================== */

/* --- Fonts. Self-hosted; paths are relative to THIS file (assets/css/). ---
   Cerotu is the wordmark face and is NOT bundled: no redistribution licence.
   It is fetched same-origin from /fonts/cerotu.otf, which the host nginx
   proxies to the already-licensed copy on nexuspool.io. If that hop fails the
   stack falls back to Sora, which is why every rule lists it. */
@font-face{font-family:'Cerotu';font-style:normal;font-weight:400;font-display:swap;
  src:url('/fonts/cerotu.otf') format('opentype')}
@font-face{font-family:'Sora';font-style:normal;font-weight:100 800;font-display:swap;
  src:url('../fonts/sora-variable-latin.woff2') format('woff2')}
@font-face{font-family:'Geist';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('../fonts/geist-variable-latin.woff2') format('woff2')}
@font-face{font-family:'Geist Mono';font-style:normal;font-weight:100 900;font-display:swap;
  src:url('../fonts/geist-mono-variable-latin.woff2') format('woff2')}

:root{
  --bg:#09090b; --bg-1:#0d0f14; --bg-2:#13161d; --bg-3:#191d27;
  --line:rgba(255,255,255,.08); --line-2:rgba(255,255,255,.14);
  --text:#eceef2; --muted:#8b93a1; --muted-2:#7b8494;
  --teal:#01b2aa; --teal-soft:#3fe0d8; --teal-glow:rgba(1,178,170,.34);
  --signal:#33e6a4; --warn:#ffb454; --danger:#ff5d5d; --ink:#04211f;
  --maxw:1200px;
  --boxw:1240px;   /* boxed content column for the archive strip + card grid */
  --font-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;
  --sans:var(--gh-font-body,'Geist',var(--font-sans-serif));
  --display:var(--gh-font-heading,'Sora',var(--font-sans-serif));
  --mono:'Geist Mono',ui-monospace,Menlo,Courier,monospace;
  /* The recognised custom-property names for the admin's font customisation,
     aliased onto the brand faces. */
  --gh-font-heading:'Sora',var(--font-sans-serif);
  --gh-font-body:'Geist',var(--font-sans-serif);
  --font-mono:'Geist Mono',Menlo,Courier,monospace;
  --ease:cubic-bezier(.22,1,.36,1);
  /* The platform injects its accent colour as a custom property; nginx renames
     it at the front door to strip the platform name. Alias it rather than fight
     it — the fallback is the brand teal, so a failed rewrite still renders. */
  --accent:var(--np-accent-color,#01b2aa);
}

*,*::before,*::after{box-sizing:border-box}
html{background:var(--bg);-webkit-text-size-adjust:100%;font-size:100%}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--sans);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale}
img{max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2px solid var(--teal-soft);outline-offset:3px}
::selection{background:rgba(1,178,170,.3)}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;scroll-behavior:auto!important}
}
.hf-viewport{display:flex;flex-direction:column;min-height:100vh}
.hf-main{flex:1 0 auto}

/* --- nav ----------------------------------------------------------------- */
.hf-nav{display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:16px clamp(16px,3vw,40px);border-bottom:1px solid rgba(255,255,255,.06);
  position:relative;z-index:3}
.hf-brand{display:inline-flex;align-items:center;gap:9px}
.hf-brand-mark{height:26px;width:auto;border-radius:6px;display:block}
.hf-brand-name{font-family:'Cerotu',var(--display);font-weight:400;font-size:17px;
  letter-spacing:.01em;color:var(--text)}
.hf-brand-sub{color:var(--muted-2);font-family:var(--display);font-size:15px}
.hf-navlinks ul{display:flex;gap:20px;list-style:none;margin:0;padding:0;flex-wrap:wrap}
.hf-navlinks a{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-2);transition:color .18s var(--ease)}
.hf-navlinks a:hover{color:var(--teal-soft)}
.hf-navlinks .nav-current a{color:var(--teal-soft)}

.hf-dot{width:6px;height:6px;background:var(--signal);display:inline-block;
  box-shadow:0 0 8px var(--signal);animation:hfPulse 2.4s infinite}
.hf-dot--warn{background:var(--warn);box-shadow:0 0 8px var(--warn)}
@keyframes hfPulse{0%,100%{opacity:1}50%{opacity:.35}}
.hf-eyebrow{font-family:var(--mono);font-size:10px;letter-spacing:.22em;
  text-transform:uppercase;color:var(--teal-soft);display:flex;align-items:center;
  gap:9px;margin-bottom:18px}

/* --- hero: the newest post ----------------------------------------------- */
.hf-hero{position:relative;min-height:clamp(380px,52vh,520px);display:flex;
  align-items:flex-end;border-bottom:1px solid var(--line-2);overflow:hidden}
.hf-hero-field{position:absolute;inset:0;width:100%;height:100%;display:block}
.hf-hero::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,var(--bg) 4%,rgba(9,9,11,.82) 42%,rgba(9,9,11,.15) 100%)}
.hf-hero-inner{position:relative;z-index:2;padding:clamp(28px,4vw,58px);
  max-width:760px;width:100%}
.hf-hero-title{font-family:var(--display);font-weight:700;
  font-size:clamp(28px,5vw,58px);line-height:1.0;letter-spacing:-.04em;
  margin:0 0 18px;max-width:17ch;text-wrap:balance}
.hf-hero-title a{transition:color .2s var(--ease)}
.hf-hero-title a:hover{color:var(--teal-soft)}
.hf-hero-excerpt{color:var(--muted);font-size:16px;line-height:1.6;max-width:50ch;
  margin:0 0 20px}
.hf-hero-meta{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-2);display:flex;gap:18px;flex-wrap:wrap;
  font-variant-numeric:tabular-nums}

/* --- archive strip + card grid ------------------------------------------- */
.hf-archive-bar{display:flex;justify-content:space-between;align-items:center;
  gap:16px;flex-wrap:wrap;
  /* full-bleed hairline, boxed content — so the label lines up with the grid */
  padding:14px max(clamp(16px,3vw,40px),calc((100% - var(--boxw))/2));
  border-bottom:1px solid var(--line-2);font-family:var(--mono);font-size:10px;
  letter-spacing:.18em;text-transform:uppercase;color:var(--muted-2)}
/* Boxed rather than bleeding to the viewport edges, and four columns at desktop
   so each thumbnail is ~30% larger than the previous six-across.
   Hairlines come from each card's OUTLINE, not from a gap-coloured container
   background: with a fixed column count the last row can hold empty cells, and
   a coloured container would show through them as grey blocks. An outline is
   drawn outside the border box, so two neighbours meet exactly in the 1px gap. */
.hf-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(268px,1fr));
  gap:1px;background:transparent;max-width:var(--boxw);margin-inline:auto;
  padding:1px}
.hf-card{background:var(--bg);padding:22px clamp(16px,2.4vw,26px) 26px;display:block;
  outline:1px solid var(--line);
  transition:background .22s var(--ease)}
.hf-card:hover{background:var(--bg-1)}
.hf-plate{width:100%;aspect-ratio:16/10;display:block;border:1px solid var(--line);
  background:var(--bg-1);margin-bottom:16px}
.hf-card-title{font-family:var(--display);font-weight:600;font-size:17px;
  line-height:1.3;letter-spacing:-.015em;margin:0 0 8px;
  transition:color .22s var(--ease);text-wrap:balance}
.hf-card:hover .hf-card-title{color:var(--teal-soft)}
.hf-card-excerpt{margin:0 0 12px;color:var(--muted);font-size:13.5px;line-height:1.6}
.hf-card-meta{font-family:var(--mono);font-size:10px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--muted-2);font-variant-numeric:tabular-nums}

/* Four across at desktop. 1240px box / 4 = ~309px per card, versus ~237px
   when it was six across full-width — about a 30% larger thumbnail. */
@media (min-width:1100px){ .hf-grid{grid-template-columns:repeat(4,1fr)} }
@media (min-width:760px) and (max-width:1099px){ .hf-grid{grid-template-columns:repeat(3,1fr)} }
@media (min-width:520px) and (max-width:759px){ .hf-grid{grid-template-columns:repeat(2,1fr)} }
/* The read-next strip only ever holds two cards; auto-fit keeps them from
   being stretched across four tracks. */
.hf-readnext .hf-grid{grid-template-columns:repeat(auto-fit,minmax(268px,1fr))}

/* --- collection heads (tag / author) ------------------------------------- */
.hf-collection-head{padding:clamp(34px,5vw,64px) clamp(16px,3vw,40px) clamp(22px,3vw,34px);
  border-bottom:1px solid var(--line-2)}
.hf-collection-title{font-family:var(--display);font-weight:700;
  font-size:clamp(26px,4vw,44px);line-height:1.04;letter-spacing:-.035em;
  margin:0 0 12px;text-wrap:balance}
.hf-collection-desc{color:var(--muted);font-size:16px;line-height:1.65;
  max-width:56ch;margin:0 0 14px}
.hf-collection-meta{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-2)}

/* --- article -------------------------------------------------------------- */
.hf-banner{position:relative;height:clamp(180px,24vw,280px);overflow:hidden;
  border-bottom:1px solid var(--line-2)}
.hf-banner-field{position:absolute;inset:0;width:100%;height:100%;display:block}
.hf-banner::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(9,9,11,.3) 0%,var(--bg) 96%)}
.hf-article-inner{padding:0 clamp(16px,3vw,40px) 70px;max-width:860px}
.hf-article-head{margin-top:-64px;position:relative;z-index:2}
.hf-article-head--page{margin-top:0;padding-top:clamp(34px,5vw,62px)}
.hf-article-title{font-family:var(--display);font-weight:700;
  font-size:clamp(26px,3.8vw,44px);line-height:1.04;letter-spacing:-.035em;
  margin:0 0 16px;max-width:19ch;text-wrap:balance}
.hf-article-meta{font-family:var(--mono);font-size:10.5px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--muted-2);display:flex;gap:18px;flex-wrap:wrap;
  padding-bottom:18px;border-bottom:1px solid var(--line);margin-bottom:34px;
  font-variant-numeric:tabular-nums}
.hf-lead{font-size:19px;line-height:1.6;color:var(--text);margin:0 0 1.3em;max-width:66ch}
.hf-feature-image{margin:0 0 2em}
.hf-feature-image img{width:100%;border:1px solid var(--line);border-radius:10px;display:block}
.hf-feature-image figcaption{font-family:var(--mono);font-size:11px;
  letter-spacing:.06em;color:var(--muted-2);text-align:center;margin-top:10px}

.hf-article-foot{margin-top:46px;padding-top:22px;border-top:1px solid var(--line);
  display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;align-items:center}
.hf-byline{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-2)}
.hf-byline a{color:var(--muted)}
.hf-tags{display:flex;gap:8px;flex-wrap:wrap}
.hf-tag{font-family:var(--mono);font-size:10px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--teal-soft);border:1px solid rgba(1,178,170,.22);
  background:rgba(1,178,170,.08);border-radius:20px;padding:4px 10px;
  transition:border-color .2s,color .2s}
.hf-tag:hover{color:var(--signal);border-color:rgba(51,230,164,.35)}
.hf-readnext{border-top:1px solid var(--line-2)}

/* --- rendered post body ---------------------------------------------------
   The mockup only showed prose. A real post also renders headings, lists,
   quotes, code, images, embeds and editor cards — all of it styled here so a
   published post never falls back to browser defaults. */
.hf-content{font-size:16.5px;line-height:1.72;color:#cdd2da;max-width:70ch;
  /* A 64-char block hash or a long URL is normal content on this blog and would
     otherwise push the whole page sideways on a phone. */
  overflow-wrap:break-word}
/* Vertical rhythm. Every child is zeroed at the SAME specificity as the
   adjacent-sibling rule, so the later one wins and spacing actually applies.
   The earlier version paired this with `.hf-content p{margin:0}` — one class
   plus one type, which outranks `.hf-content > * + *` and silently collapsed
   every paragraph gap in every article to zero. Never re-add a type-selector
   margin reset here. */
.hf-content > *{margin-top:0;margin-bottom:0}
.hf-content > * + *{margin-top:1.3em}
.hf-content strong{color:var(--text);font-weight:600}
.hf-content em{font-style:italic}
.hf-content a{color:var(--teal-soft);text-decoration:underline;
  text-underline-offset:3px;text-decoration-thickness:1px;
  text-decoration-color:rgba(63,224,216,.4);transition:color .18s,text-decoration-color .18s}
.hf-content a:hover{color:var(--signal);text-decoration-color:var(--signal)}
.hf-content h2,.hf-content h3,.hf-content h4{font-family:var(--display);
  color:var(--text);letter-spacing:-.02em;line-height:1.24;text-wrap:balance}
.hf-content h2{font-size:clamp(20px,2.3vw,25px);font-weight:600;margin-top:2.1em}
.hf-content h3{font-size:19px;font-weight:600;margin-top:1.8em}
.hf-content h4{font-size:16.5px;font-weight:600;margin-top:1.6em}
.hf-content ul,.hf-content ol{padding-left:1.35em}
.hf-content li{margin-bottom:.55em}
.hf-content li::marker{color:var(--teal)}
.hf-content blockquote{margin-inline:0;padding:2px 0 2px 20px;
  border-left:2px solid var(--teal);color:var(--text);font-size:18px;line-height:1.65}
.hf-content hr{border:0;border-top:1px solid var(--line);margin:2.4em 0}
.hf-content img,.hf-content video{border-radius:10px;border:1px solid var(--line);display:block}
.hf-content figure{margin-inline:0}
.hf-content figcaption{font-family:var(--mono);font-size:11px;letter-spacing:.06em;
  color:var(--muted-2);text-align:center;margin-top:10px}
.hf-content code{font-family:var(--mono);font-size:.86em;background:var(--bg-2);
  border:1px solid var(--line);border-radius:5px;padding:.14em .42em;color:var(--teal-soft)}
.hf-content pre{background:var(--bg-1);border:1px solid var(--line);border-radius:10px;
  padding:18px 20px;overflow-x:auto;font-family:var(--mono);font-size:13px;
  line-height:1.65;color:#cdd2da}
.hf-content pre code{background:none;border:0;padding:0;font-size:inherit;color:inherit}
.hf-content table{border-collapse:collapse;font-size:13.5px}
.hf-content th{background:var(--bg-1);text-align:left;padding:10px 14px;
  font-family:var(--mono);font-size:9.5px;letter-spacing:.17em;text-transform:uppercase;
  color:var(--muted-2);font-weight:400;border-bottom:1px solid var(--line-2)}
.hf-content td{padding:12px 14px;border-bottom:1px solid var(--line);
  color:var(--muted);vertical-align:top;line-height:1.55}
.hf-content td:first-child{color:var(--text)}
/* wide things scroll inside themselves; the page body never scrolls sideways */
.hf-content .hf-scroll,.hf-content figure.kg-width-wide,
.hf-content table{display:block;overflow-x:auto;max-width:100%;width:100%}
.hf-content .kg-card,.hf-content .kg-embed-card{margin-inline:0}
.hf-content .kg-width-full img,.hf-content .kg-width-wide img{width:100%}
.hf-content .kg-bookmark-card a{text-decoration:none}
.hf-content .kg-bookmark-container{display:flex;border:1px solid var(--line);
  border-radius:10px;overflow:hidden;background:var(--bg-1);color:inherit}
.hf-content .kg-bookmark-content{padding:18px 20px;flex:1;min-width:0}
.hf-content .kg-bookmark-title{color:var(--text);font-weight:600;font-size:15px}
.hf-content .kg-bookmark-description{color:var(--muted);font-size:13.5px;margin-top:6px}
.hf-content .kg-bookmark-metadata{color:var(--muted-2);font-size:12px;margin-top:10px;
  font-family:var(--mono)}

/* --- pagination ----------------------------------------------------------- */
.hf-pagination{display:flex;align-items:center;justify-content:center;gap:22px;
  padding:30px clamp(16px,3vw,40px) 46px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.14em;text-transform:uppercase}
.hf-page-link{color:var(--teal-soft);transition:color .18s}
.hf-page-link:hover{color:var(--signal)}
.hf-page-link.is-off{color:var(--muted-2);opacity:.45}
.hf-page-count{color:var(--muted-2);font-variant-numeric:tabular-nums}

/* --- error ---------------------------------------------------------------- */
.hf-error{padding:clamp(48px,9vw,110px) clamp(16px,3vw,40px)}
.hf-error-inner{max-width:620px}
.hf-error-code{font-family:var(--display);font-weight:800;
  font-size:clamp(64px,13vw,150px);line-height:.86;letter-spacing:-.05em;
  color:transparent;-webkit-text-stroke:1px var(--muted-2);margin-bottom:16px}
.hf-error-title{font-family:var(--display);font-weight:600;
  font-size:clamp(21px,3vw,30px);line-height:1.14;letter-spacing:-.03em;margin:0 0 12px}
.hf-error-help{color:var(--muted);font-size:15.5px;line-height:1.65;margin:0 0 22px}
.hf-error-link{font-family:var(--mono);font-size:11px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--teal-soft)}
.hf-error-link:hover{color:var(--signal)}
.hf-error-details{margin-top:34px;border-top:1px solid var(--line);padding-top:18px;
  font-family:var(--mono);font-size:12px;color:var(--muted)}
.hf-error-details ul{padding-left:1.1em}
.hf-error-details span{display:block;color:var(--muted-2);font-size:11px}

/* A page with title+feature image hidden still needs top breathing room. */
.hf-article-head--bare{padding-top:clamp(34px,5vw,62px)}

/* The read-next strip is emitted unconditionally (see post.hbs); hide it when
   neither neighbour resolved, so a lone post never shows an empty bordered bar. */
.hf-readnext:not(:has(.hf-row)){display:none}

/* Embedded video had no rule at all, so a YouTube card rendered at its raw
   200x113 attribute size. */
.hf-content .kg-embed-card{display:block}
.hf-content .kg-embed-card iframe,.hf-content iframe{width:100%;aspect-ratio:16/9;
  height:auto;border:0;border-radius:10px;display:block}
/* The editor's own card stylesheet loads after this one, so the bookmark card
   needs the surface stated explicitly or it renders as a white box on dark. */
.hf-content .kg-bookmark-card,.hf-content .kg-bookmark-container{background:var(--bg-1);
  color:var(--text)}
.hf-content .kg-bookmark-container{border-color:var(--line)}


/* --- release widget (left sidebar on articles) ---------------------------- */
/* Populated at runtime from the pool's own /api/pool, proxied same-origin.
   Ships `hidden` and only reveals when a real version arrives — a widget that
   invents a version number is worse than no widget. */
.hf-release{border:1px solid var(--line);background:var(--bg-1);padding:18px 18px 16px;
  position:sticky;top:22px;align-self:start}
.hf-release[hidden]{display:none}
.hf-release-head{display:flex;align-items:center;gap:8px;font-family:var(--mono);
  font-size:9.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--muted-2);
  padding-bottom:12px;border-bottom:1px solid var(--line)}
.hf-release-version{font-family:var(--display);font-weight:700;
  font-size:clamp(24px,2.4vw,31px);line-height:1;letter-spacing:-.035em;
  color:var(--text);margin:14px 0 2px;font-variant-numeric:tabular-nums}
.hf-release-stats{margin:16px 0 0;display:grid;gap:1px;background:var(--line);
  border:1px solid var(--line)}
.hf-release-stats > div{background:var(--bg-1);display:flex;justify-content:space-between;
  align-items:baseline;gap:10px;padding:9px 11px}
.hf-release-stats dt{font-family:var(--mono);font-size:9.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted-2);margin:0}
.hf-release-stats dd{margin:0;font-family:var(--mono);font-size:12.5px;color:var(--text);
  font-variant-numeric:tabular-nums}
.hf-release-link{display:inline-block;margin-top:15px;font-family:var(--mono);
  font-size:10px;letter-spacing:.15em;text-transform:uppercase;color:var(--teal-soft);
  transition:color .18s}
.hf-release-link:hover{color:var(--signal)}

/* --- article layout: widget left, article right --------------------------- */
.hf-article-layout{display:block}
@media (min-width:1100px){
  /* Centred so the article is not pinned to the left edge with dead space beside it. */
  .hf-article-layout{max-width:1240px;margin-inline:auto;
    padding-left:clamp(16px,3vw,40px);padding-right:clamp(16px,3vw,40px)}
  /* Two columns ONLY once the widget has actually rendered. A display:none grid
     item is removed from the grid, not just made invisible — so an unguarded
     grid put the ARTICLE into the 264px sidebar track whenever the widget's
     fetch failed, rendering the whole post 264px wide. Measured, not theorised.
     Without :has() support this stays one column, which is the safe direction. */
  .hf-article-layout:has(.hf-release:not([hidden])){display:grid;
    grid-template-columns:264px minmax(0,1fr);gap:clamp(26px,3vw,52px)}
  .hf-article-layout:has(.hf-release:not([hidden])) .hf-release{margin-top:0}
  .hf-article-layout:has(.hf-release:not([hidden])) .hf-article-inner{padding-left:0;
    padding-right:0;max-width:none}
}
@media (max-width:1099px){
  /* stacked: the writing comes first, the widget follows it */
  /* align-self:start comes from the base rule (correct in the grid, where it
     stops the widget stretching to full column height). In this COLUMN flex
     container the same value means shrink-to-content instead, which rendered
     the widget as a 183px box floating at the left of a 375px screen. */
  .hf-release{position:static;align-self:stretch;width:auto;
    margin:0 clamp(16px,3vw,40px) 40px;order:2}
  .hf-article-layout{display:flex;flex-direction:column}
  .hf-article-layout .hf-article-inner{order:1}
}

/* --- card thumbnails: the post's real feature image ----------------------- */
.hf-card-image{width:100%;aspect-ratio:16/10;object-fit:cover;display:block;
  border:1px solid var(--line);margin-bottom:16px;background:var(--bg-1)}

/* ==========================================================================
   Footer — Hashfield's own. Full-bleed with a hairline rule rather than the
   main site's floating rounded card, mono column labels matching the /// Archive
   strip, no glow and no giant background wordmark. The shared np-footer
   component is untouched and still used by the forum.
   ========================================================================== */
.hf-footer{border-top:1px solid var(--line-2);background:var(--bg-1);margin-top:auto}
.hf-footer-top{display:grid;grid-template-columns:1.7fr 1fr 1fr 1fr;
  gap:clamp(24px,3.4vw,52px);padding:clamp(34px,4.4vw,54px) clamp(16px,3vw,40px)
  clamp(26px,3vw,38px);max-width:var(--maxw);margin:0 auto;width:100%}
.hf-footer-brand{display:inline-flex;align-items:center;gap:10px;margin-bottom:13px}
.hf-footer-brand img{border-radius:6px;display:block}
.hf-footer-brand-name{font-family:'Cerotu',var(--display);font-weight:400;font-size:19px;
  letter-spacing:.01em;color:var(--text)}
.hf-footer-tagline{color:var(--muted);font-size:13.5px;line-height:1.6;max-width:34ch;margin:0}
.hf-footer-badges{display:flex;flex-wrap:wrap;gap:7px;margin-top:15px}
.hf-footer-badge{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--teal-soft);background:rgba(1,178,170,.08);
  border:1px solid rgba(1,178,170,.22);padding:4px 9px}
.hf-footer-col{display:flex;flex-direction:column;align-items:flex-start}
.hf-footer-heading{font-family:var(--mono);font-size:9.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--muted-2);margin:0 0 15px;font-weight:400;
  display:inline-flex;align-items:center;gap:7px}
.hf-footer-heading::before{content:"";width:16px;height:1px;flex-shrink:0;
  background:linear-gradient(90deg,var(--teal),transparent)}
.hf-footer-link{color:var(--muted);font-size:13.5px;margin-bottom:10px;
  transition:color .18s var(--ease)}
.hf-footer-link:hover{color:var(--teal-soft)}
.hf-footer-bar{border-top:1px solid var(--line);display:flex;justify-content:space-between;
  align-items:center;gap:16px;flex-wrap:wrap;padding:15px clamp(16px,3vw,40px);
  max-width:var(--maxw);margin:0 auto;width:100%}
.hf-footer-social{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.hf-footer-soc{color:var(--muted-2);display:inline-flex;transition:color .18s,transform .18s}
.hf-footer-soc:hover{color:var(--teal-soft);transform:translateY(-2px)}
.hf-footer-unit{font-family:var(--mono);font-size:9.5px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--muted-2)}
.hf-footer-barcode{display:inline-block;width:48px;height:12px;opacity:.4;
  background:repeating-linear-gradient(90deg,var(--muted-2) 0 1px,transparent 1px 2px,
    var(--muted-2) 2px 4px,transparent 4px 5px,var(--muted-2) 5px 6px,
    transparent 6px 8px,var(--muted-2) 8px 9px,transparent 9px 12px)}
.hf-footer-copy{font-family:var(--mono);font-size:11px;color:var(--muted-2);margin:0}
.hf-footer-copy a{color:var(--teal-soft);transition:color .18s}
.hf-footer-copy a:hover{color:var(--signal)}
.hf-footer-legal{border-top:1px solid var(--line);padding:14px clamp(16px,3vw,40px)}
.hf-footer-legal p{max-width:var(--maxw);margin:0 auto;font-size:11px;line-height:1.65;
  color:var(--muted);text-align:center}
.hf-footer-legal strong{color:var(--text);font-weight:600}
.hf-footer-legal a{color:var(--teal-soft)}
.hf-footer-legal a:hover{color:var(--teal)}
@media (max-width:1024px){.hf-footer-top{grid-template-columns:1fr 1fr}}
@media (max-width:560px){.hf-footer-top{grid-template-columns:1fr}}

/* --- mobile chrome -------------------------------------------------------- */
/* The nav was a single flex row: brand on the left, four uppercase mono links
   on the right. Below ~700px those links wrap into the brand and the bar turns
   into visual noise. Stack them instead — brand on its own line, links on a
   single row that scrolls horizontally if they do not fit, with the scrollbar
   hidden so it reads as a quiet strip rather than a broken menu. */
@media (max-width:760px){
  .hf-nav{flex-direction:column;align-items:stretch;gap:0;padding:0}
  .hf-brand{padding:13px clamp(14px,4vw,20px);align-self:flex-start}
  .hf-navlinks{border-top:1px solid rgba(255,255,255,.06);overflow-x:auto;
    -webkit-overflow-scrolling:touch;scrollbar-width:none}
  .hf-navlinks::-webkit-scrollbar{display:none}
  .hf-navlinks ul{flex-wrap:nowrap;gap:0;padding:0 clamp(6px,2vw,12px);width:max-content}
  .hf-navlinks li{flex:0 0 auto}
  .hf-navlinks a{display:block;padding:11px 12px;font-size:10px;letter-spacing:.13em;
    white-space:nowrap}
  /* the hero sits directly under a now-taller bar; keep its text off the edge */
  .hf-hero{min-height:clamp(320px,46vh,420px)}
}
/* The grid's 258px track floor overflows a very narrow phone; below that let a
   single column simply take the width it has. */
@media (max-width:300px){
  .hf-grid{grid-template-columns:1fr}
}

/* ==========================================================================
   DISPATCH — portada por secciones
   Arquitectura medida sobre github.blog: UN contenedor, UN gap, y cada seccion
   con su propia rejilla. La jerarquia la hace el layout, no el cuerpo de letra
   (alla los titulos de seccion miden 12-16px; aca tambien).
   Nada de esto se escala: los tamanos son los definitivos.
   ========================================================================== */
:root{ --box:1232px; --gap:48px; }

.hf-in{max-width:var(--box);margin-inline:auto;padding-inline:clamp(18px,3vw,32px)}
.hf-sec{padding-top:72px}
.hf-sec--lead{padding-top:52px}

/* Encabezado de seccion: 12px en mono. Deliberadamente pequeno. */
.hf-sech{display:flex;align-items:baseline;justify-content:space-between;gap:20px;
  padding-bottom:18px;margin-bottom:32px;border-bottom:1px solid var(--line-2)}
.hf-sech-t{font-family:var(--mono);font-size:12px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--text);margin:0;font-weight:500}
.hf-sech-a{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--teal-soft);white-space:nowrap;
  transition:opacity .18s var(--ease)}
.hf-sech-a:hover{opacity:.72}

/* Etiqueta de tema y meta, compartidas por todas las secciones */
.hf-kick{font-family:var(--mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--teal);margin:0 0 11px}
.hf-meta{font-family:var(--mono);font-size:12px;color:var(--muted-2);margin:0;
  font-variant-numeric:tabular-nums}

/* --- fila de categorias -------------------------------------------------- */
.hf-cats{border-bottom:1px solid var(--line);background:var(--bg-1)}
.hf-cats-in{max-width:var(--box);margin-inline:auto;padding-inline:clamp(18px,3vw,32px);
  display:flex;overflow-x:auto;scrollbar-width:none}
.hf-cats-in::-webkit-scrollbar{display:none}
.hf-cat{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);padding:13px 18px;
  border-right:1px solid var(--line);white-space:nowrap;
  transition:color .18s var(--ease),background .18s var(--ease)}
.hf-cat:first-child{border-left:1px solid var(--line)}
.hf-cat:hover{color:var(--text)}
.hf-cat.is-on{color:var(--teal-soft);background:var(--bg)}

/* --- barra de estado del pool ------------------------------------------- */
.hf-live{max-width:var(--box);margin-inline:auto;padding-inline:clamp(18px,3vw,32px)}
.hf-live[hidden]{display:none}
.hf-live-in{display:flex;flex-wrap:wrap;border:1px solid var(--line);border-top:0;
  background:var(--bg-1)}
.hf-live-in>div{padding:11px 20px;border-right:1px solid var(--line);flex:1 1 auto;min-width:118px}
.hf-live-in b{display:block;font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted-2);margin-bottom:4px;font-weight:400}
.hf-live-in span{font-family:var(--mono);font-size:13px;color:var(--text);
  font-variant-numeric:tabular-nums;display:block}
.hf-live-go{color:var(--signal);display:flex;align-items:center;gap:7px}
.hf-live-go .hf-dot{width:5px;height:5px}

/* --- 1 - destacados: 1fr / 1fr ------------------------------------------ */
.hf-feat{display:grid;grid-template-columns:1fr;gap:var(--gap)}
@media (min-width:1000px){ .hf-feat{grid-template-columns:1fr 1fr} }
.hf-lead-img{display:block;aspect-ratio:592/314;position:relative;overflow:hidden;
  background:var(--bg-2);margin-bottom:22px}
.hf-lead-img img,.hf-lead-img canvas{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}
.hf-lead-title{font-family:var(--display);font-weight:700;font-size:clamp(26px,3.2vw,34px);
  line-height:1.1;letter-spacing:-.04em;margin:0 0 14px;text-wrap:balance}
.hf-lead-title a{transition:color .18s var(--ease)}
.hf-lead-title a:hover{color:var(--teal-soft)}
.hf-lead-excerpt{color:var(--muted);font-size:17px;line-height:1.58;margin:0 0 16px;max-width:52ch}
.hf-side{display:flex;flex-direction:column;gap:26px}
.hf-item{display:grid;grid-template-columns:1fr 132px;gap:22px;align-items:start;
  padding-bottom:26px;border-bottom:1px solid var(--line)}
.hf-item:last-child{border-bottom:0;padding-bottom:0}
.hf-item-title{font-family:var(--display);font-weight:600;font-size:19px;line-height:1.28;
  letter-spacing:-.025em;margin:0 0 10px;text-wrap:balance}
.hf-item-title a{transition:color .18s var(--ease)}
.hf-item-title a:hover{color:var(--teal-soft)}

/* Miniatura cuadrada: el recorte 1:1 alinea la columna pase lo que pase con
   el aspecto de la imagen original. */
.hf-sq{display:block;aspect-ratio:1;position:relative;overflow:hidden;background:var(--bg-2)}
.hf-sq img,.hf-sq canvas{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}
.hf-wide{display:block;aspect-ratio:284/151;position:relative;overflow:hidden;
  background:var(--bg-2);margin-bottom:15px}
.hf-wide img,.hf-wide canvas{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block}

/* --- 2 - ultimas + registro --------------------------------------------- */
.hf-two{display:grid;grid-template-columns:1fr;gap:var(--gap);align-items:start}
@media (min-width:1000px){ .hf-two{grid-template-columns:1fr 372px} }
.hf-list{display:flex;flex-direction:column}
.hf-row{display:grid;grid-template-columns:1fr 132px;gap:22px;align-items:start;
  padding:24px 0;border-bottom:1px solid var(--line)}
.hf-row:first-child{padding-top:0}
.hf-row-title{font-family:var(--display);font-weight:600;font-size:20px;line-height:1.28;
  letter-spacing:-.025em;margin:0 0 9px;text-wrap:balance}
.hf-row-title a{transition:color .18s var(--ease)}
.hf-row-title a:hover{color:var(--teal-soft)}
.hf-row-excerpt{font-size:15.5px;line-height:1.55;color:var(--muted);margin:0 0 10px;max-width:60ch}

/* --- 3 - serie: lead cuadrada + dos pilas ------------------------------- */
.hf-serie{display:grid;grid-template-columns:1fr;gap:var(--gap);align-items:start}
@media (min-width:760px){ .hf-serie{grid-template-columns:1fr 1fr} }
@media (min-width:1100px){ .hf-serie{grid-template-columns:1fr 284px 284px} }
.hf-sq--lead{margin-bottom:22px}
.hf-serie-title{font-family:var(--display);font-weight:700;font-size:clamp(22px,2.4vw,27px);
  line-height:1.14;letter-spacing:-.035em;margin:0 0 12px;text-wrap:balance}
.hf-serie-title a{transition:color .18s var(--ease)}
.hf-serie-title a:hover{color:var(--teal-soft)}
.hf-stack{display:flex;flex-direction:column;gap:26px}
.hf-scard-title{font-family:var(--display);font-weight:600;font-size:17px;line-height:1.3;
  letter-spacing:-.02em;margin:0 0 9px;text-wrap:balance}
.hf-scard-title a{transition:color .18s var(--ease)}
.hf-scard-title a:hover{color:var(--teal-soft)}

/* --- 4 - por tema: cuatro columnas -------------------------------------- */
/* auto-FILL, no auto-fit: con un solo tema, auto-fit colapsa las pistas vacias
   y estira esa columna a todo el ancho del contenedor (medido: 1168px). */
.hf-four{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:var(--gap)}
.hf-topic-h{display:block;font-family:var(--mono);font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--teal);margin-bottom:14px;padding-bottom:12px;
  border-bottom:1px solid var(--line);transition:color .18s var(--ease)}
.hf-topic-h:hover{color:var(--teal-soft)}
.hf-topic-l{display:block;font-family:var(--display);font-weight:500;font-size:15.5px;
  line-height:1.34;letter-spacing:-.015em;margin-bottom:14px;color:#d6dae2;
  transition:color .18s var(--ease)}
.hf-topic-l:hover{color:var(--teal-soft)}
.hf-topic-c{font-family:var(--mono);font-size:11px;color:var(--muted-2);margin:0}

/* --- el riel de version, ahora al lado de Latest ------------------------ */
/* En la portada es una pieza del flujo, no una barra lateral fija; dentro del
   articulo conserva el comportamiento que ya tenia. */
.hf-two .hf-release{position:static;width:auto;align-self:stretch;margin:0;top:auto}

.hf-main>.hf-pagination{margin-top:64px}

/* ==========================================================================
   ARTICULO — columna de lectura de 660px a 20px
   El tema servia 92 caracteres por linea; el rango legible es 65-75.
   ========================================================================== */
.hf-read-wrap{max-width:var(--box);margin-inline:auto;padding-inline:clamp(18px,3vw,32px)}
.hf-artgrid{display:grid;grid-template-columns:1fr;gap:34px;align-items:start;padding-top:38px}
@media (min-width:1100px){
  .hf-artgrid{grid-template-columns:210px minmax(0,660px) 1fr;gap:44px}
}
.hf-toc{display:none}
@media (min-width:1100px){
  .hf-toc{display:block;position:sticky;top:24px}
}
.hf-toc b{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted-2);margin-bottom:14px;font-weight:400}
.hf-toc a{display:block;font-size:13.5px;color:var(--muted);padding:7px 0 7px 13px;
  border-left:1px solid var(--line);line-height:1.4;transition:color .18s var(--ease)}
.hf-toc a:hover{color:var(--text)}
.hf-toc a.is-on{color:var(--teal-soft);border-left-color:var(--teal-soft)}
.hf-side-rail{display:none}
@media (min-width:1100px){ .hf-side-rail{display:block;position:sticky;top:24px} }
.hf-side-rail b{display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted-2);margin-bottom:12px;font-weight:400}
.hf-side-rail .box{border:1px solid var(--line);background:var(--bg-1)}
.hf-side-rail .box span{display:block;padding:11px 14px;font-family:var(--mono);font-size:12px;
  color:var(--muted);border-bottom:1px solid var(--line);font-variant-numeric:tabular-nums}
.hf-side-rail .box span:last-child{border-bottom:0}

/* Barra de progreso de lectura: 2px, el unico elemento que sigue al scroll. */
.hf-progress{position:fixed;top:0;left:0;height:2px;width:0;background:var(--teal-soft);
  z-index:50;transition:width .08s linear}
@media (prefers-reduced-motion:reduce){ .hf-progress{transition:none} }

/* --- medida de lectura del articulo -------------------------------------
   El tema servia 16.5px con max-width:70ch, que a 660px de columna daba 92
   caracteres por linea. La columna ahora la fija la rejilla, asi que aca solo
   se sube el cuerpo y se suelta el tope de caracteres. */
.hf-artgrid .hf-content{font-size:20px;line-height:1.6;max-width:none;color:#d6dae2}
.hf-artgrid .hf-content > * + *{margin-top:1.3em}
.hf-artgrid .hf-lead{font-size:21px;line-height:1.55;color:var(--muted);max-width:60ch}
.hf-artgrid .hf-feature-image img{border-radius:0}

/* El encabezado del articulo ya no monta sobre el banner: con la columna
   centrada, el solapamiento dejaba el titulo fuera del eje de lectura. */
.hf-read-wrap .hf-article-head{margin-top:0;padding-top:clamp(30px,4vw,52px);
  max-width:820px}
.hf-read-wrap .hf-article-title{margin-bottom:16px}

/* --- medida de lectura en pantallas chicas ------------------------------
   Medido a 375px: 20px sobre columna de 339px da 34 caracteres, muy por
   debajo del piso comodo. 17px lleva la linea a ~40, que es el rango normal
   de lectura en telefono. */
@media (max-width:767px){
  .hf-artgrid .hf-content{font-size:17px;line-height:1.62}
  .hf-artgrid .hf-lead{font-size:18px}
  .hf-read-wrap .hf-article-head{padding-top:26px}
}
@media (min-width:768px) and (max-width:1099px){
  .hf-artgrid .hf-content{font-size:19px}
}

/* ==========================================================================
   PULIDO — los detalles que separan la retícula correcta de un acabado premium.
   Cada regla sale de medir github.blog contra lo que este tema servía.
   ========================================================================== */
:root{ --radius:10px; --radius-sm:8px; }

/* --- 1. Esquinas. Toda imagen del sistema. -------------------------------
   Era lo primero que delataba el acabado: canto vivo en cada miniatura. */
.hf-lead-img,.hf-sq,.hf-wide{border-radius:var(--radius);overflow:hidden}
.hf-artgrid .hf-feature-image img{border-radius:var(--radius)}
.hf-lead-img img,.hf-lead-img canvas,
.hf-sq img,.hf-sq canvas,
.hf-wide img,.hf-wide canvas{border-radius:inherit}

/* --- 2. Regla gruesa sobre cada sección ----------------------------------
   github.blog abre cada bloque con una barra pesada arriba, no con un hairline
   abajo. Es el acento que le da peso editorial a un titulo de 15px. */
.hf-sech{border-top:3px solid var(--text);border-bottom:1px solid var(--line);
  padding-top:16px;padding-bottom:16px;margin-bottom:36px;align-items:center}
.hf-sech-t{font-size:15px;letter-spacing:.02em;text-transform:none;font-weight:600;
  font-family:var(--display)}
.hf-sech-a{font-size:13px;letter-spacing:.01em;text-transform:none;
  font-family:var(--sans);font-weight:500}

/* --- 3. Ritmo vertical ---------------------------------------------------- */
.hf-sec{padding-top:96px}
.hf-sec--lead{padding-top:56px}

/* --- 4. El destacado manda de verdad -------------------------------------- */
.hf-lead-title{font-size:clamp(30px,3.8vw,44px);line-height:1.05;letter-spacing:-.045em;
  margin-bottom:16px}
.hf-lead-excerpt{font-size:17px;line-height:1.6;margin-bottom:18px}

/* --- 5. Imagen a la IZQUIERDA, y mas grande ------------------------------
   github sirve 168px; este tema servia 132 con la imagen a la derecha, que
   invierte el orden de lectura de toda la columna. */
.hf-item{grid-template-columns:168px 1fr;gap:20px;align-items:start;
  padding-bottom:28px}
.hf-row{grid-template-columns:200px 1fr;gap:24px;align-items:start;padding:28px 0}
@media (max-width:600px){
  .hf-item,.hf-row{grid-template-columns:104px 1fr;gap:16px}
}
.hf-item-title{font-size:19px;line-height:1.3;margin-bottom:8px}
.hf-row-title{font-size:21px;line-height:1.3;margin-bottom:8px}
.hf-item-excerpt{font-size:14.5px;line-height:1.55;color:var(--muted);margin:0 0 12px}
.hf-row-excerpt{font-size:15px;line-height:1.58;margin-bottom:12px}
.hf-scard-excerpt{font-size:14px;line-height:1.55;color:var(--muted);margin:0 0 12px}

/* --- 6. Firma: autor y fecha ---------------------------------------------
   Lo que mas hace que una rejilla se lea EDITADA en vez de generada. */
.hf-by{display:flex;align-items:center;gap:8px;margin:0;flex-wrap:wrap}
.hf-by-av{width:20px;height:20px;border-radius:50%;display:block;flex:none}
.hf-by-name{font-family:var(--sans);font-size:13px;font-weight:600;color:var(--text)}
.hf-by-sep{color:var(--muted-2);font-size:12px}
.hf-by-date{font-family:var(--mono);font-size:12px;color:var(--muted-2);
  font-variant-numeric:tabular-nums}

/* --- 7. La etiqueta de tema, enlazable y con mas presencia --------------- */
.hf-kick{display:inline-block;font-size:12px;letter-spacing:.06em;text-transform:none;
  font-weight:600;font-family:var(--sans);color:var(--teal-soft);margin-bottom:10px;
  transition:color .18s var(--ease)}
.hf-kick:hover{color:var(--text)}

/* --- 8. Quiebre de fondo, sin salir del dark-only ------------------------
   github alterna secciones claras para marcar ritmo. La marca es dark-only,
   asi que el quiebre se hace por ELEVACION: la serie sube a --bg-1 y sangra
   de borde a borde, con su contenido igual encajado en el contenedor. */
.hf-sec--band{background:var(--bg-1);border-block:1px solid var(--line);
  max-width:none;padding-inline:0;margin-top:96px;padding-top:0;padding-bottom:88px}
.hf-sec--band > *{max-width:var(--box);margin-inline:auto;
  padding-inline:clamp(18px,3vw,32px)}
.hf-sec--band .hf-sech{margin-top:0;padding-top:56px;border-top-width:3px}

/* --- 9. Tarjetas de la serie --------------------------------------------- */
.hf-serie-title{font-size:clamp(22px,2.6vw,28px);margin-bottom:12px}
.hf-scard-title{font-size:17px;line-height:1.3;margin-bottom:8px}

/* --- 10. Barra de estado y categorias: menos caja, mas aire -------------- */
.hf-live-in{border-radius:var(--radius-sm)}
.hf-cat{letter-spacing:.04em;text-transform:none;font-family:var(--sans);
  font-size:13.5px;font-weight:500;padding:14px 20px;border-right:0}
.hf-cat:first-child{border-left:0}
.hf-cats-in{gap:4px}
.hf-cat.is-on{background:transparent;color:var(--teal-soft);
  box-shadow:inset 0 -2px 0 var(--teal-soft)}
.hf-cat:hover{color:var(--text)}

/* --- 11. Foco visible sobre las nuevas superficies redondeadas ----------- */
.hf-sq:focus-visible,.hf-lead-img:focus-visible,.hf-wide:focus-visible{
  outline:2px solid var(--teal-soft);outline-offset:3px}

/* ==========================================================================
   NORMALIZACION FINAL
   El audit sobre la pagina viva encontro 18 tamanos de letra distintos y 14
   valores de espaciado fuera de la base. Eso es sedimento de parches
   sucesivos, y es exactamente lo que hace que un diseno se lea "casi bien".
   Aca la escala se declara una vez y todo se ancla a ella.
   El articulo (.hf-content) queda FUERA a proposito: es un contexto de lectura
   larga con su propia escala de 20px, y aplanarlo a 15 lo arruinaria.
   ========================================================================== */
:root{
  /* Ocho pasos. Nada fuera de esta lista en la portada y las colecciones. */
  --t-micro:11px;   /* etiqueta mono */
  --t-meta:13px;    /* autor, fecha, enlaces de seccion */
  --t-body:15px;    /* resumenes, titulo de seccion, categoria */
  --t-lede:17px;    /* resumen del destacado, titulo de item */
  --t-row:20px;     /* titulo de fila */
  --t-card:24px;    /* titulo de tarjeta grande */
  --t-serie:28px;   /* cabeza de serie */
  --t-display:44px; /* destacado */

  /* Espaciado: multiplos de 4, sin excepciones. */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px;
  --s6:24px; --s8:32px; --s10:40px; --s12:48px; --s14:56px; --s24:96px;
}

/* --- tipografia anclada ---------------------------------------------------- */
.hf-lead-title{font-size:clamp(30px,3.8vw,var(--t-display))}
.hf-lead-excerpt{font-size:var(--t-lede)}
.hf-serie-title{font-size:clamp(22px,2.6vw,var(--t-serie))}
.hf-row-title{font-size:var(--t-row)}
.hf-item-title,.hf-scard-title{font-size:var(--t-lede)}
.hf-sech-t{font-size:var(--t-body)}
.hf-sech-a,.hf-by-name,.hf-by-date,.hf-by-sep{font-size:var(--t-meta)}
.hf-item-excerpt,.hf-row-excerpt,.hf-scard-excerpt,.hf-topic-l{font-size:var(--t-body)}
.hf-kick,.hf-cat{font-size:var(--t-body)}
.hf-meta,.hf-topic-c,.hf-topic-h{font-size:var(--t-micro)}
.hf-live-in span{font-size:var(--t-meta)}
.hf-live-in b{font-size:var(--t-micro)}
.hf-navlinks a{font-size:var(--t-micro)}
.hf-release-link,.hf-page-link,.hf-page-count{font-size:var(--t-meta)}

/* --- espaciado anclado ----------------------------------------------------- */
.hf-kick{margin-bottom:var(--s3)}
.hf-item-title,.hf-row-title{margin-bottom:var(--s2)}
.hf-item-excerpt,.hf-row-excerpt,.hf-scard-excerpt{margin-bottom:var(--s3)}
.hf-lead-title{margin-bottom:var(--s4)}
.hf-lead-excerpt{margin-bottom:var(--s5)}
.hf-lead-img{margin-bottom:var(--s6)}
.hf-sq--lead{margin-bottom:var(--s6)}
.hf-wide{margin-bottom:var(--s4)}
.hf-item{gap:var(--s5);padding-bottom:var(--s8)}
.hf-row{gap:var(--s6);padding-block:var(--s8)}
.hf-side,.hf-stack{gap:var(--s8)}
.hf-sech{padding-block:var(--s4);margin-bottom:var(--s10)}
.hf-by{gap:var(--s2)}

/* --- objetivos tactiles ----------------------------------------------------
   El audit encontro seis enlaces bajo 32px de alto. En escritorio se perdona;
   en un telefono es un objetivo que se falla. El area se agranda con padding
   negativo-compensado para no mover el ritmo visual ni un pixel. */
@media (max-width:767px){
  .hf-kick,.hf-sech-a,.hf-topic-h,.hf-release-link,.hf-page-link{
    position:relative;display:inline-flex;align-items:center;min-height:44px;
    margin-block:-12px}
  .hf-cat{min-height:44px;display:inline-flex;align-items:center}
}

/* ==========================================================================
   MOTION
   Un solo lenguaje: 420ms de entrada, 180ms de respuesta al puntero, la misma
   curva en todo. Solo transform y opacity — nunca layout.
   A PRUEBA DE FALLOS: el contenido nace VISIBLE y es el JS el que agrega la
   clase que lo oculta. Si el script no corre, la pagina se ve entera.
   ========================================================================== */
.hf-reveal{opacity:0;transform:translate3d(0,10px,0)}
.hf-reveal.is-in{opacity:1;transform:none;
  transition:opacity .42s var(--ease),transform .42s var(--ease);
  transition-delay:calc(var(--i,0) * 60ms)}

/* Respuesta tactil: el enlace se hunde 1px al presionar. */
.hf-lead-title a:active,.hf-row-title a:active,.hf-item-title a:active,
.hf-serie-title a:active,.hf-scard-title a:active,.hf-topic-l:active{
  transform:translate3d(0,1px,0)}

/* La miniatura acerca la imagen al pasar el puntero. Escala la IMAGEN dentro
   de un contenedor que recorta, asi el bloque no se mueve y no empuja al
   vecino — un transform sobre la tarjeta entera desalinea la columna. */
/* Gate de puntero fino: sin el, un toque en un telefono dispara el hover y la
   imagen queda ampliada hasta el proximo toque en otro lado. Y 220ms, no 500:
   la respuesta al puntero vive en 150-250ms; medio segundo deja la imagen
   moviendose despues de que el ojo ya llego al titulo. */
@media (hover:hover) and (pointer:fine){
  .hf-sq img,.hf-sq canvas,.hf-lead-img img,.hf-lead-img canvas,
  .hf-wide img,.hf-wide canvas{transition:transform .22s var(--ease)}
  .hf-item:hover .hf-sq img,.hf-item:hover .hf-sq canvas,
  .hf-row:hover .hf-sq img,.hf-row:hover .hf-sq canvas,
  .hf-lead:hover .hf-lead-img img,.hf-lead:hover .hf-lead-img canvas,
  .hf-scard:hover .hf-wide img,.hf-scard:hover .hf-wide canvas,
  .hf-serie-lead:hover .hf-sq img,.hf-serie-lead:hover .hf-sq canvas{
    transform:scale(1.03)}
}

/* La regla de seccion se dibuja al entrar: 3px de barra creciendo de izquierda
   a derecha. Es el unico gesto decorativo del sistema y dura 520ms. */
.hf-sech{position:relative;border-top-color:transparent}
.hf-sech::before{content:"";position:absolute;top:-3px;left:0;height:3px;
  width:100%;background:var(--text);transform:scaleX(0);transform-origin:left}
.hf-sech.is-in::before{transform:scaleX(1);transition:transform .52s var(--ease)}
.hf-sech:not(.hf-reveal)::before{transform:scaleX(1)}

@media (prefers-reduced-motion:reduce){
  .hf-reveal,.hf-reveal.is-in{opacity:1;transform:none;transition:none}
  .hf-sech::before{transform:scaleX(1);transition:none}
  .hf-sq img,.hf-sq canvas,.hf-lead-img img,.hf-lead-img canvas,
  .hf-wide img,.hf-wide canvas{transition:none}
  .hf-item:hover .hf-sq img,.hf-row:hover .hf-sq img,
  .hf-lead:hover .hf-lead-img img{transform:none}
}

/* El widget de version usaba 9.5/12.5px, fuera de la escala. El footer conserva
   sus propios 9.5px a proposito: es un port fiel de la web de NexusPool y se
   pidio intacto, asi que su escala es suya y no la de este tema. */
.hf-release-stats dt{font-size:var(--t-micro)}
.hf-release-stats dd{font-size:var(--t-meta)}
.hf-release-head{font-size:var(--t-micro)}

/* Ultimo valor fuera de escala que encontro el audit sobre produccion: el
   numero de version salia a 31px, mas grande que cualquier titulo de seccion.
   Baja al paso de 24, que sigue leyendose como la cabeza del widget. */
.hf-release-version{font-size:var(--t-card)}

/* (4) Un solo radio. Convivian 8px y 10px sin regla que lo justificara, que es
   deriva, no sistema. */
:root{ --radius-sm:var(--radius); }

/* (5) La paginacion medía 21px de alto: es el control mas chico de la pagina y
   el que mas se falla con el cursor. 44px tambien en escritorio, compensado con
   margen negativo para no mover el ritmo. */
.hf-page-link{display:inline-flex;align-items:center;min-height:44px}
.hf-pagination{align-items:center}

/* Los marcadores de posicion eran un em-dash, prohibido sin excepcion. Ahora el
   hueco nace vacio, asi que reserva su alto para que la barra no salte cuando
   /np/pool.json responde. */
.hf-live-in span,.hf-release-stats dd{min-height:1.2em}
