/* =========================================================================
   Article / photo personality layer  (article-fx.css + article-fx.js)
   Used by skryfwerk.html (reader overlay + card grid), pos-static.html and
   foto-static.html. A writer's desk: ink, paper, lens.

   Every hidden "before" state is gated behind html.ax, which article-fx.js
   only sets when it is running and the visitor does not prefer reduced
   motion — so without the script (or with reduced motion) content is simply
   shown. No overflow:hidden / clip masks are put around Northwell text.
   Easing tokens come from motion.css (--hl-ez-expo / -spring / -inout).
   ========================================================================= */

:root{
  --ax-ink: #000000;
  --ax-gold: #555555;
  --ax-expo: var(--hl-ez-expo, cubic-bezier(.19,1,.22,1));
  --ax-spring: var(--hl-ez-spring, cubic-bezier(.16,1,.3,1));
  --ax-inout: var(--hl-ez-inout, cubic-bezier(.76,0,.24,1));
  --ax-out: cubic-bezier(.22,.61,.36,1);   /* calm ease-out, no overshoot: reader open / settle */
}

/* ------------------------------------------------------------------
   1. PEN PROGRESS LINE — a plain thin ink line along the top as you read
      (plain thin line, no marker).
   ------------------------------------------------------------------ */
.ax-pen{
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 1300;
  pointer-events: none; opacity: 0; transition: opacity .5s ease;
}
.ax-pen.is-on{ opacity: 1; }
.ax-pen.ax-pen-reader{ z-index: 502; }
.ax-pen-line{
  position: absolute; inset: 0; transform-origin: 0 50%; transform: scaleX(0);
  background: linear-gradient(90deg, rgba(15,15,15,.55), var(--ax-ink) 70%, var(--ax-gold));
  box-shadow: 0 1px 6px rgba(143,143,143,.45);
  border-radius: 0 3px 3px 0;
}
html.ax-pen-page .hl-progress{ display: none; }

/* ------------------------------------------------------------------
   2. HERO — title words rise out of the ink, meta line draws in
   ------------------------------------------------------------------ */
html.ax .ax-title .ax-w{
  display: inline-block; opacity: 0; filter: blur(10px);
  transform: translate3d(0,.5em,0) rotate(2.5deg) scale(1.05); transform-origin: 0 100%;
}
html.ax .ax-on .ax-title .ax-w{
  animation: axInk 1.5s var(--ax-expo) both;
  animation-delay: calc(var(--axb, .2s) + var(--i, 0) * .1s);
}
@keyframes axInk{
  0%   { opacity: 0; filter: blur(10px); transform: translate3d(0,.5em,0) rotate(2.5deg) scale(1.05); text-shadow: 0 0 .18em rgba(15,15,15,.55); }
  45%  { opacity: .9; filter: blur(3px); text-shadow: 0 0 .1em rgba(15,15,15,.35); }
  100% { opacity: 1; filter: blur(0); transform: none; text-shadow: 0 0 0 rgba(15,15,15,0); }
}

/* the small rule before the label draws itself, then date + tag follow */
html.ax .post-hero .label::before{
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform 1s var(--ax-expo);
}
html.ax .ax-on .label::before{ transform: none; transition-delay: var(--axb, .2s); }
html.ax .ax-on .label > *{
  animation: axRiseSoft .9s var(--ax-expo) both;
  animation-delay: calc(var(--axb, .2s) + .12s);
}
html.ax .ax-on .label > .ptag{
  animation: axStamp .8s var(--ax-spring) both;
  animation-delay: calc(var(--axb, .2s) + .32s);
}
@keyframes axRiseSoft{ from{ opacity:0; transform: translate3d(0,10px,0); filter: blur(3px); } to{ opacity:1; transform:none; filter:none; } }
/* the tag is stamped on like a rubber stamp */
@keyframes axStamp{
  0%  { opacity:0; transform: scale(1.7) rotate(-5deg); }
  55% { opacity:1; transform: scale(.94) rotate(1deg); }
  100%{ opacity:1; transform: none; }
}

html.ax .ax-on .subtitle,
html.ax .ax-on #post-caption{
  animation: axRiseSoft 1.2s var(--ax-expo) both;
  animation-delay: calc(var(--axb, .2s) + .55s);
}

html.ax .ax-on .post-meta-row .stat{
  animation: axRiseSoft .9s var(--ax-expo) both;
  animation-delay: calc(var(--axb, .2s) + .75s);
}
html.ax .ax-on .post-meta-row .stat + .stat{ animation-delay: calc(var(--axb, .2s) + .9s); }
html.ax .ax-on .post-meta-row .stat svg{ animation: axBeat 1.1s var(--ax-spring) both; animation-delay: calc(var(--axb, .2s) + 1.1s); }
@keyframes axBeat{ 0%{transform:scale(1);} 30%{transform:scale(1.35);} 55%{transform:scale(.92);} 100%{transform:scale(1);} }

/* pos page: the body block no longer fades as one lump — its paragraphs do */
html.ax .post-body.post-open-line{ opacity: 1 !important; transform: none !important; }

/* cover image develops slowly, like a print in the tray */
html.ax .post-cover .frame{
  filter: blur(9px) grayscale(.9) brightness(1.15);
  transform: scale(1.08);
  transition: filter 2.2s var(--ax-expo), transform 2.8s var(--ax-expo);
}
html.ax .post-cover.ax-go .frame{ filter: none; transform: none; }
/* in the reader the ghost thumbnail already flew in; keep the real one calm */
html.ax #readerCoverWrap .frame{ filter: none; transform: scale(1.03); transition: transform 2.4s var(--ax-expo); }
html.ax #readerCoverWrap.is-visible .frame{ transform: none; }

/* ------------------------------------------------------------------
   3. BODY — paragraphs settle onto the page as you read
   ------------------------------------------------------------------ */
html.ax .ax-r:not(.ax-in){ opacity: 0; transform: translate3d(0,22px,0); filter: blur(2.5px); }
html.ax .ax-r{
  transition: opacity 1s ease, transform 1.2s var(--ax-expo), filter .9s ease;
  transition-delay: calc(var(--axd, 0) * 70ms);
}
html.ax .ax-r.ax-in{ opacity: 1; transform: none; filter: none; }
html.ax h2.ax-r:not(.ax-in), html.ax h3.ax-r:not(.ax-in){ transform: translate3d(-14px,14px,0); letter-spacing: .04em; }
html.ax h2.ax-r, html.ax h3.ax-r{ transition-property: opacity, transform, filter, letter-spacing; }
html.ax h2.ax-r.ax-in, html.ax h3.ax-r.ax-in{ letter-spacing: 0; }

/* drop cap: the first letter is inked in, then settles */
.post-body .ax-drop{
  float: left; font-family: 'Fraunces', serif; font-weight: 500; font-style: normal;
  font-size: 4.9em; line-height: .78; padding: .06em .12em 0 0; margin: .02em .04em 0 -.02em;
  color: var(--brown-deep, #000000);
  text-shadow: 1px 1px 0 rgba(143,143,143,.35);
  transform-origin: 30% 80%;
}
html.ax .ax-r:not(.ax-in) .ax-drop{ opacity: 0; transform: scale(1.7) rotate(-6deg); filter: blur(8px); }
html.ax .ax-r .ax-drop{ transition: opacity 1s ease .25s, transform 1.4s var(--ax-spring) .25s, filter 1s ease .25s; }
html.ax .ax-r.ax-in .ax-drop{ opacity: 1; transform: none; filter: none; }

/* blockquotes: an ink rule draws down the side; a big quote mark fades in behind */
html.ax .post-body blockquote.ax-q{ border-left-color: transparent; position: relative; isolation: isolate; }
html.ax blockquote.ax-q::before{
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; border-radius: 2px;
  background: linear-gradient(180deg, var(--ax-gold), var(--ax-ink));
  transform: scaleY(0); transform-origin: 50% 0; transition: transform 1.5s var(--ax-inout) .15s;
}
html.ax blockquote.ax-q.ax-in::before{ transform: none; }
html.ax blockquote.ax-q::after{
  content: '\201C'; position: absolute; left: .5rem; top: -.55em; z-index: -1;
  font-family: 'Fraunces', serif; font-style: normal; font-size: 5.5rem; line-height: 1; color: var(--ax-gold);
  opacity: 0; transform: scale(.5) rotate(-12deg); transform-origin: 30% 70%;
  transition: opacity 1.2s ease .5s, transform 1.4s var(--ax-spring) .5s;
}
html.ax blockquote.ax-q.ax-in::after{ opacity: .2; transform: none; }

/* images develop like a photograph in the tray: blur + no colour -> sharp + colour */
html.ax .ax-dev{
  filter: blur(14px) grayscale(1) brightness(1.25) contrast(.75);
  transform: scale(1.03);
  transition: filter 2.2s var(--ax-expo) .1s, transform 2.4s var(--ax-expo) .1s, opacity 1s ease;
}
html.ax .ax-in .ax-dev, html.ax .ax-dev.ax-in{ filter: none; transform: none; }
html.ax img.ax-dev.ax-r:not(.ax-in){ opacity: 0; }
html.ax .ax-hasimg.ax-r:not(.ax-in){ filter: none; transform: none; opacity: 1; }
html.ax .ax-r.ax-hr:not(.ax-in){ transform: scaleX(.2); }

/* ------------------------------------------------------------------
   4. LIKE BUTTON burst
   ------------------------------------------------------------------ */
.like-btn{ position: relative; }
.like-btn.liked svg{ animation: axHeart .8s var(--ax-spring); }
@keyframes axHeart{ 0%{transform:scale(1);} 25%{transform:scale(1.7);} 50%{transform:scale(.88);} 75%{transform:scale(1.25);} 100%{transform:scale(1.1);} }
.ax-burst{
  position: absolute; left: 24px; top: 50%; pointer-events: none; z-index: 3;
  font-size: var(--s, 12px); line-height: 1; color: var(--c, #111111);
  animation: axBurst 1.25s var(--ax-expo) forwards;
}
@keyframes axBurst{
  0%   { opacity: 0; transform: translate(-50%,-50%) scale(.2) rotate(0); }
  20%  { opacity: 1; }
  70%  { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) scale(1) rotate(var(--r)); }
}
.ax-burst-ring{
  position: absolute; left: 24px; top: 50%; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%;
  border: 2px solid var(--ax-gold); pointer-events: none; opacity: 0;
  animation: axRing .9s var(--ax-expo) forwards;
}
@keyframes axRing{ 0%{opacity:.9; transform:scale(.4);} 100%{opacity:0; transform:scale(7);} }

/* ------------------------------------------------------------------
   5. COMMENTS, RELATED CARDS, AUTHOR CARD
   ------------------------------------------------------------------ */
html.ax .ax-c:not(.ax-in){ opacity: 0; transform: translate3d(-18px,26px,0); }
html.ax .ax-c{
  transition: opacity .9s ease, transform 1.1s var(--ax-expo);
  transition-delay: calc(var(--axd, 0) * 90ms);
}
html.ax .ax-c.ax-in{ opacity: 1; transform: none; }
html.ax .ax-c.ax-instant{ transition: none !important; }
html.ax .ax-c .comment-avatar{ transition: transform .8s var(--ax-spring) calc(var(--axd, 0) * 90ms + .2s); }
html.ax .ax-c:not(.ax-in) .comment-avatar{ transform: scale(.3) rotate(-30deg); }
html.ax .ax-c.ax-instant .comment-avatar{ transition: none !important; }

html.ax .related-card.ax-c:not(.ax-in){ transform: translate3d(0,60px,0) rotate(-2.2deg) scale(.95); transform-origin: 0 100%; }
html.ax .related-card.ax-c:nth-child(2):not(.ax-in){ transform: translate3d(0,60px,0) rotate(1.6deg) scale(.95); transform-origin: 100% 100%; }
html.ax .related-card.ax-c{ transition: opacity .9s ease, transform 1.3s var(--ax-expo), box-shadow .5s ease; transition-delay: calc(var(--axd, 0) * 120ms); }
html.ax .related-card.ax-c.ax-in:hover{ transition-delay: 0s; }
html.ax .related-card.ax-c:not(.ax-in) .related-thumb{ transform: scale(1.18); }
html.ax .related-card.ax-c .related-thumb{ transition: transform 1.8s var(--ax-expo); }
.related-card{ position: relative; }
.related-body h4{ transition: color .3s ease, transform .6s var(--ax-expo); }
.related-card .related-tag::after{ content: ' \2192'; display: inline-block; opacity: 0; transform: translateX(-8px); transition: opacity .3s ease, transform .5s var(--ax-spring); }
@media (hover:hover){
  .related-card:hover .related-body h4{ transform: translateX(4px); }
  .related-card:hover .related-tag::after{ opacity: 1; transform: none; }
}

/* author card: a ring draws round the avatar, name/role follow */
.author-avatar{ position: relative; }
.ax-ring{ position: absolute; inset: -6px; width: calc(100% + 12px); height: calc(100% + 12px); transform: rotate(-90deg); pointer-events: none; overflow: visible; }
.ax-ring circle{ fill: none; stroke: var(--ax-gold); stroke-width: 1.4; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; }
html.ax .ax-au:not(.ax-in) .author-avatar{ transform: scale(.4) rotate(-40deg); opacity: 0; }
html.ax .ax-au .author-avatar{ transition: transform 1.2s var(--ax-spring), opacity .6s ease; }
html.ax .ax-au.ax-in .ax-ring circle{ stroke-dashoffset: 0; transition: stroke-dashoffset 1.8s var(--ax-inout) .3s; }
html.ax .ax-au:not(.ax-in) .author-name, html.ax .ax-au:not(.ax-in) .author-role{ opacity: 0; transform: translateX(-16px); letter-spacing: .12em; }
html.ax .ax-au .author-name, html.ax .ax-au .author-role{ transition: opacity .9s ease, transform 1.1s var(--ax-expo), letter-spacing 1.4s var(--ax-expo); }
html.ax .ax-au.ax-in .author-name{ transition-delay: .35s; }
html.ax .ax-au.ax-in .author-role{ transition-delay: .5s; }
@media (hover:hover){
  .author-avatar{ transition: transform .8s var(--ax-spring); }
  .author-card:hover .author-avatar{ transform: rotate(14deg) scale(1.06); }
}

/* back link with a hover arrow */
.ax-nav{ max-width: var(--post-col, 760px); margin: 3rem auto 0; padding: 0 5vw; }
.ax-back{
  display: inline-flex; align-items: center; gap: .8rem; font-size: .78rem; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-soft, #4a4a4a); padding: .5rem 0; position: relative;
}
.ax-back svg{ width: 22px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.5; transition: transform .6s var(--ax-spring); }
@media (hover:hover){
  .ax-back:hover{ color: var(--brown-deep, #000000); }
  .ax-back:hover svg{ transform: translateX(-8px); }
}
html.ax .ax-nav{ transition: opacity 1s ease, transform 1.2s var(--ax-expo); }
html.ax .ax-nav:not(.ax-in){ opacity: 0; transform: translateY(20px); }

/* ------------------------------------------------------------------
   6. PHOTO PAGE — the picture develops with a lens-focus pull
   ------------------------------------------------------------------ */
html.ax-foto .photo-frame img{
  filter: blur(18px) grayscale(1) brightness(1.3) contrast(.7);
  transform: scale(1.06);
}
html.ax-foto .photo-frame.ax-go img{ animation: axFocus 3s var(--ax-expo) both; }
@keyframes axFocus{
  0%   { filter: blur(18px) grayscale(1) brightness(1.3) contrast(.7); transform: scale(1.06); }
  35%  { filter: blur(4px)  grayscale(.7) brightness(1.15) contrast(.85); transform: scale(1.03); }
  52%  { filter: blur(9px)  grayscale(.5) brightness(1.1) contrast(.9); transform: scale(1.04); }
  80%  { filter: blur(0)    grayscale(.1)  brightness(1.02) contrast(1); transform: scale(1); }
  100% { filter: blur(0) grayscale(0) brightness(1) contrast(1); transform: scale(1); }
}
.photo-frame img{ transition: transform 1.8s var(--ax-expo); }
@media (hover:hover){
  .photo-frame:hover img{ transform: scale(1.035); }
}
/* viewfinder brackets + focus-lock ring + shutter flash */
.ax-vf{ position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.ax-vf i{ position: absolute; width: 34px; height: 34px; border: 0 solid rgba(255,255,255,.92); opacity: 0; filter: drop-shadow(0 0 2px rgba(0,0,0,.35)); }
.ax-vf i:nth-child(1){ left: 16px; top: 16px; border-width: 2px 0 0 2px; }
.ax-vf i:nth-child(2){ right: 16px; top: 16px; border-width: 2px 2px 0 0; }
.ax-vf i:nth-child(3){ left: 16px; bottom: 16px; border-width: 0 0 2px 2px; }
.ax-vf i:nth-child(4){ right: 16px; bottom: 16px; border-width: 0 2px 2px 0; }
.ax-vf .fr{
  position: absolute; left: 50%; top: 50%; width: 70px; height: 70px; margin: -35px 0 0 -35px;
  border: 1.5px solid rgba(255,255,255,.95); border-radius: 3px; opacity: 0; filter: drop-shadow(0 0 2px rgba(0,0,0,.35));
}
.ax-vf .fl{ position: absolute; inset: 0; background: #fff; opacity: 0; }
.photo-frame.ax-go .ax-vf i{ animation: axBracket 2.6s var(--ax-expo) .1s both; }
.photo-frame.ax-go .ax-vf .fr{ animation: axFocusRing 1.3s var(--ax-expo) 1.5s both; }
.photo-frame.ax-go .ax-vf .fl{ animation: axFlash .7s ease-out 1.9s both; }
@keyframes axBracket{
  0%   { opacity: 0; transform: scale(2.6); }
  25%  { opacity: 1; transform: scale(1); }
  75%  { opacity: 1; }
  100% { opacity: 0; transform: scale(.85); }
}
.ax-vf i:nth-child(1), .ax-vf i:nth-child(3){ transform-origin: 0 50%; }
@keyframes axFocusRing{
  0%   { opacity: 0; transform: scale(2.2); }
  35%  { opacity: 1; transform: scale(.85); }
  55%  { opacity: 1; transform: scale(1); border-color: #c1c1c1; }
  100% { opacity: 0; transform: scale(1); border-color: #c1c1c1; }
}
@keyframes axFlash{ 0%{opacity:0;} 15%{opacity:.28;} 100%{opacity:0;} }

/* ------------------------------------------------------------------
   7. SKRYFWERK GRID CARDS — tilt to the cursor and folded corner
   ------------------------------------------------------------------ */
.blog-card h3{ transition: color .3s ease, transform .6s var(--ax-expo); }
.blog-card::before, .blog-card::after{
  content: ''; position: absolute; right: 0; bottom: 0; width: 0; height: 0; pointer-events: none; z-index: 3;
  transition: width .55s var(--ax-spring), height .55s var(--ax-spring);
}
/* the page cut away... */
.blog-card::before{ background: var(--cream, #ffffff); clip-path: polygon(100% 0, 100% 100%, 0 100%); }
/* ...and the folded flap lying over it */
.blog-card::after{
  background: linear-gradient(315deg, #bababa 0%, #dcdcdc 45%, #fafafa 100%);
  clip-path: polygon(0 0, 100% 0, 0 100%);
  box-shadow: -3px -3px 8px rgba(0,0,0,.18);
}
.blog-thumb::before{
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: 0; transition: opacity .5s ease;
  background: radial-gradient(circle at var(--mx, 50%) var(--my, 30%), rgba(255,255,255,.34), transparent 55%);
}
@media (hover:hover) and (pointer:fine){
  .blog-card:hover h3{ transform: translateX(4px); }
  .blog-card:hover::before, .blog-card:hover::after{ width: 44px; height: 44px; }
  .blog-card.ax-tilting .blog-thumb::before{ opacity: 1; }
  html body .blog-grid .blog-card.ax-tilting:hover{
    transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(-6px) scale(1.018);
    transition: transform .25s var(--ax-expo), box-shadow .5s var(--ax-expo), opacity .6s ease;
  }
}

/* ------------------------------------------------------------------
   8. READER OVERLAY — the article opens (cover picture flies in, content settles)
   ------------------------------------------------------------------ */
html.ax .reader-section{
  transform: translate3d(0,24px,0);
  transition: opacity .6s var(--ax-out), transform .7s var(--ax-out);
}
html.ax .reader-section.is-visible{ transform: none; }
html.ax #readerCoverWrap.reader-section{ transform: none; transition: opacity .5s ease; }
/* content settles in just after the paper starts to fade in */
html.ax .reader-overlay-panel.ax-opening .reader-section{ transition-delay: .12s; }
/* the real hero picture stays out of sight while the flying one travels, then is simply there beneath it */
html.ax .reader-overlay-panel.ax-ghosting #readerCoverWrap{ opacity: 0; transition: none; }
html.ax .reader-overlay-panel.ax-ghosting.ax-landed #readerCoverWrap{ opacity: 1; }
/* the real picture's soft top shade and white foot are left out while the ghost stands in for it (the ghost has none),
   and ease in once it takes over, so nothing pops */
html.ax #readerCoverWrap::before, html.ax #readerCoverWrap::after{ transition: opacity .45s ease; }
html.ax .reader-overlay-panel.ax-ghosting #readerCoverWrap::before, html.ax .reader-overlay-panel.ax-ghosting #readerCoverWrap::after{ opacity: 0; transition: none; }
html.ax #readerCoverWrap .frame{ filter: none; transform: none; transition: none; }

/* The panel is always full-screen; the page's own card-rect morph is neutralised.
   Its paper fades (opacity only); no shadow, no will-change, no backdrop blur. */
html.ax .reader-overlay-panel{
  top: 0 !important; left: 0 !important; width: 100vw !important; height: 100vh !important;
  border-radius: 0; box-shadow: none !important; overflow-x: hidden; will-change: auto;
  transition: opacity .45s var(--ax-out) !important;
}
@supports (height: 100dvh){ html.ax .reader-overlay-panel{ height: 100dvh !important; } }
html.ax .reader-overlay-panel:not(.is-open){ transition: opacity .38s cubic-bezier(.4,0,.2,1) !important; }
html.ax .reader-overlay-backdrop, html.ax .reader-overlay-backdrop.is-open{ background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; transition: none; }
/* the clicked card steps aside while its picture flies out (and back in on close) */
html.ax .blog-card.is-open-source{ opacity: 0; transition: opacity .2s ease !important; }

/* the flying picture (article-fx.js makeGhost): clipped box + picture, transform/opacity only */
.ax-ghost{ position: fixed; left: 0; top: 0; z-index: 502; -webkit-mask-image: linear-gradient(#000, #000); mask-image: linear-gradient(#000, #000); transform-origin: 0 0; pointer-events: none; will-change: transform, opacity; }
.ax-ghost-img{ position: absolute; background-size: 100% 100%; background-repeat: no-repeat; transform-origin: 50% 50%; will-change: transform; }
/* home page: quick fade to paper before navigating */
.ax-veil{ position: fixed; inset: 0; z-index: 2000; background: var(--paper, #fff); opacity: 0; pointer-events: auto; will-change: opacity; }

/* Reader content: rises in, no blur, no overshoot, no rotation */
html.ax #readerOverlayPanel .ax-title .ax-w{ filter: none; transform: translate3d(0,16px,0); }
html.ax #readerOverlayPanel .ax-on .ax-title .ax-w{ animation: axRise .7s var(--ax-out) both; animation-delay: calc(var(--axb, .1s) + var(--i, 0) * 55ms); }
html.ax #readerOverlayPanel .post-hero .label::before{ transition: transform .6s var(--ax-out); }
html.ax #readerOverlayPanel .ax-on .label > *{ animation: axRise .6s var(--ax-out) both; animation-delay: calc(var(--axb, .1s) + .05s); }
html.ax #readerOverlayPanel .ax-on .label > .ptag{ animation: axRise .6s var(--ax-out) both; animation-delay: calc(var(--axb, .1s) + .12s); }
html.ax #readerOverlayPanel .ax-on .subtitle{ animation: axRise .7s var(--ax-out) both; animation-delay: calc(var(--axb, .1s) + .22s); }
html.ax #readerOverlayPanel .ax-on .post-meta-row .stat{ animation: axRise .6s var(--ax-out) both; animation-delay: calc(var(--axb, .1s) + .3s); }
html.ax #readerOverlayPanel .ax-on .post-meta-row .stat + .stat{ animation-delay: calc(var(--axb, .1s) + .38s); }
html.ax #readerOverlayPanel .ax-on .post-meta-row .stat svg{ animation: none; }
@keyframes axRise{ from{ opacity: 0; transform: translate3d(0,14px,0); } to{ opacity: 1; transform: none; } }
html.ax #readerOverlayPanel .ax-r:not(.ax-in){ opacity: 0; transform: translate3d(0,18px,0); filter: none; }
html.ax #readerOverlayPanel .ax-r{ transition: opacity .6s var(--ax-out), transform .7s var(--ax-out); transition-delay: calc(var(--axd, 0) * 60ms); }
html.ax #readerOverlayPanel h2.ax-r:not(.ax-in), html.ax #readerOverlayPanel h3.ax-r:not(.ax-in){ letter-spacing: 0; }
html.ax #readerOverlayPanel .ax-r:not(.ax-in) .ax-drop{ opacity: 0; transform: none; filter: none; }
html.ax #readerOverlayPanel .ax-r .ax-drop{ transition: opacity .6s ease .1s; }
html.ax #readerOverlayPanel .ax-dev{ filter: none; transform: none; transition: opacity .6s ease; }

@media (max-width: 640px){
  .ax-drop{ font-size: 4.2em; }
  html.ax blockquote.ax-q::after{ font-size: 4.2rem; }
}

@media print{
  .ax-pen, .ax-vf, .ax-ghost, .ax-nav{ display: none !important; }
  html.ax .ax-r, html.ax .ax-c, html.ax .ax-dev, html.ax .ax-au *{ opacity: 1 !important; transform: none !important; filter: none !important; }
}

/* while the reader is open the grid page is scroll-locked: the site-wide top
   progress bar (motion.css) must not show as a second line */
body.reader-open-lock .hl-progress{ opacity: 0; }

/* ------------------------------------------------------------------
   9. THE WALL — the blog grid as a wall of pinned thoughts
   article-fx.js adds .wall to #blogGrid, gives every card its own
   --r (tilt), --dy (offset), --sp (parallax speed) and sets grid-row spans
   so columns pack like masonry. Everything below only applies with .wall.
   ------------------------------------------------------------------ */
html.ax .blog-grid.wall{
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-auto-rows: 8px; grid-auto-flow: row dense;
  column-gap: 2.2rem; row-gap: 0; align-items: start;
  padding: .5rem 0 2rem;
}
html.ax .wall .blog-card{
  align-self: start; margin-top: calc(var(--dy, 0) * 1px);
  transform: translate(var(--nx, 0px), var(--ny, 0px)) rotate(var(--r, 0deg)) scale(var(--sc, 1));
  translate: 0 var(--py, 0px);
  transform-origin: 50% 12%;
  transition: transform .7s var(--ax-expo), box-shadow .6s var(--ax-expo), opacity .4s ease;
  box-shadow: 0 1px 2px rgba(0,0,0,.06), 0 12px 26px -14px rgba(0,0,0,.32);
  will-change: transform;
}
/* 'pinned' look: a small pin mark at the top edge */
html.ax .wall .blog-card .ax-pin{
  position: absolute; top: 9px; left: 50%; width: 9px; height: 9px; margin-left: -4.5px; border-radius: 50%;
  background: var(--ink, #111); box-shadow: 0 2px 3px rgba(0,0,0,.35), inset 1px 1px 2px rgba(255,255,255,.35);
  z-index: 4; opacity: .85; pointer-events: none;
}
/* sizes: tall / landscape / square / short / feature (2 cols) / notes */
html.ax .wall .shape-tall .blog-thumb{ aspect-ratio: auto; height: 430px; }
html.ax .wall .shape-portrait .blog-thumb{ aspect-ratio: auto; height: 340px; }
html.ax .wall .shape-square .blog-thumb{ aspect-ratio: auto; height: 300px; }
html.ax .wall .shape-landscape .blog-thumb{ aspect-ratio: auto; height: 230px; }
html.ax .wall .shape-short .blog-thumb{ aspect-ratio: auto; height: 170px; }
html.ax .wall .shape-wide .blog-thumb{ aspect-ratio: auto; height: 250px; }
html.ax .wall .shape-feature{ grid-column: span 2; }
html.ax .wall .shape-feature .blog-thumb{ aspect-ratio: auto; height: 380px; }
html.ax .wall .shape-feature h3{ font-size: 1.85rem; }
html.ax .wall .shape-wide{ grid-column: span 2; }
html.ax .wall .shape-wide .blog-card-body{ padding-top: 1.2rem; }

/* typographic note: no picture, the excerpt is the card */
html.ax .wall .shape-note{ background: var(--paper, #fff); }
html.ax .wall .shape-note .blog-thumb{ display: none; }
html.ax .wall .shape-note .blog-card-body{ padding: 3.6rem 1.9rem 1.7rem; gap: 1.1rem; position: relative; }
html.ax .wall .shape-note .blog-card-body::before{
  content: '\201C'; position: absolute; left: 1.6rem; top: .9rem;
  font-family: 'Fraunces', serif; font-size: 6.4rem; line-height: 1; color: var(--ink, #111); opacity: .16;
  transition: transform .9s var(--ax-spring), opacity .5s ease;
}
html.ax .wall .shape-note p{
  order: 1; flex: none; font-family: 'Cormorant Garamond', serif; font-style: italic;
  font-size: 1.62rem; line-height: 1.36; color: var(--ink, #111);
  display: -webkit-box; -webkit-line-clamp: 8; -webkit-box-orient: vertical; overflow: hidden;
}
html.ax .wall .shape-note p:empty{ display: none; }
html.ax .wall .shape-note h3{
  order: 2; font-family: 'Jost', sans-serif; font-size: .76rem; font-weight: 400; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-soft, #4a4a4a);
  padding-top: .9rem; border-top: 1px solid var(--line, #e2e2e2);
}
html.ax .wall .shape-note .blog-meta{ order: 3; }
html.ax .wall .shape-note .read-more{ order: 4; }
html.ax .wall .shape-note:hover .blog-card-body::before{ transform: scale(1.18) rotate(-6deg); opacity: .3; }
/* every other note is inked in: white on black */
html.ax .wall .shape-note.note-ink{ background: var(--ink, #111); }
html.ax .wall .shape-note.note-ink p, html.ax .wall .shape-note.note-ink h3{ color: var(--paper, #fff); }
html.ax .wall .shape-note.note-ink h3{ border-top-color: rgba(255,255,255,.22); opacity: .8; }
html.ax .wall .shape-note.note-ink .blog-card-body::before{ color: var(--paper, #fff); opacity: .2; }
html.ax .wall .shape-note.note-ink .blog-meta, html.ax .wall .shape-note.note-ink .read-more{ color: rgba(255,255,255,.7); }
html.ax .wall .shape-note.note-ink .blog-meta .tag{ background: rgba(255,255,255,.14); color: #fff; }
html.ax .wall .shape-note.note-ink .blog-meta .dot{ background: rgba(255,255,255,.5); }

/* entrance: cards land on the wall one after another and settle */
html.ax .wall .blog-card:not(.wall-in){ opacity: 0; }
html.ax .wall .blog-card.wall-in{
  animation: axLand 1.25s var(--ax-spring) backwards;
  animation-delay: calc(var(--wi, 0) * 120ms);
}
@keyframes axLand{
  0%   { opacity: 0; transform: translate(0, 120px) rotate(calc(var(--r, 0deg) * -3 + 6deg)) scale(1.1); box-shadow: 0 60px 70px -20px rgba(0,0,0,.35); }
  22%  { opacity: 1; }
  62%  { transform: translate(0, -8px) rotate(calc(var(--r, 0deg) * 1.5)) scale(.988); }
  82%  { transform: translate(0, 2px) rotate(calc(var(--r, 0deg) * .85)) scale(1.004); }
  100% { opacity: 1; transform: translate(0, 0) rotate(var(--r, 0deg)) scale(1); }
}

/* hover: pulled off the wall, straightened; neighbours give way */
@media (hover:hover) and (pointer:fine){
  html.ax .wall .blog-card:hover, html.ax .wall .blog-card.ax-tilting:hover{
    z-index: 6; --sc: 1.035;
    transform: translate(var(--nx, 0px), var(--ny, 0px)) perspective(1100px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) rotate(0deg) translateY(-10px) scale(1.035);
    box-shadow: 0 2px 6px rgba(0,0,0,.08), 0 40px 60px -22px rgba(0,0,0,.5);
    transition: transform .3s var(--ax-expo), box-shadow .5s var(--ax-expo), opacity .4s ease;
  }
}
html.ax .wall .blog-card:active{ transform: translate(var(--nx, 0px), var(--ny, 0px)) rotate(0deg) scale(.975); }
html.ax .wall .blog-card.is-pressing{ transform: rotate(0deg) scale(.965) !important; }

/* tablet: two columns, softer tilt */
@media (max-width: 860px){
  html.ax .blog-grid.wall{ grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 1.6rem; }
  html.ax .wall .shape-tall .blog-thumb{ height: 340px; }
  html.ax .wall .shape-feature .blog-thumb{ height: 300px; }
  html.ax .wall .shape-portrait .blog-thumb{ height: 280px; }
  html.ax .wall .shape-wide .blog-thumb{ height: 220px; }
}
/* phone: one column, lighter effects (no parallax, gentler tilt) */
@media (max-width: 560px){
  html.ax .blog-grid.wall{ grid-template-columns: minmax(0, 1fr); column-gap: 0; }
  html.ax .wall .shape-feature, html.ax .wall .shape-wide{ grid-column: span 1; }
  html.ax .wall .shape-tall .blog-thumb{ height: 360px; }
  html.ax .wall .shape-portrait .blog-thumb{ height: 300px; }
  html.ax .wall .shape-square .blog-thumb{ height: 280px; }
  html.ax .wall .shape-feature .blog-thumb{ height: 260px; }
  html.ax .wall .shape-landscape .blog-thumb, html.ax .wall .shape-wide .blog-thumb{ height: 220px; }
  html.ax .wall .shape-short .blog-thumb{ height: 170px; }
  html.ax .wall .shape-note p{ font-size: 1.4rem; }
  html.ax .wall .blog-card{ translate: none; }
}
@media (prefers-reduced-motion: reduce){
  html.ax .wall .blog-card{ animation: none !important; translate: none; }
}

/* ------------------------------------------------------------------
   10. Home page row (flat wall) + shared card rules
   ------------------------------------------------------------------ */
.blog-card{ position: relative; overflow: hidden; }
.blog-card, .blog-thumb, .related-card, .related-thumb{ border-radius: 0 !important; }
html.ax .blog-grid.wall.wall-flat{ grid-auto-rows: auto; align-items: stretch; padding: 1rem 0 1.4rem; }
html.ax .wall-flat .blog-card{ margin-top: 0; align-self: stretch; }

/* ------------------------------------------------------------------
   11. CALM WALL — orderly masonry: 3 sizes, no tilt, no spotlight
   ------------------------------------------------------------------ */
html.ax .wall .blog-card{ transform: none; translate: none; margin-top: 0; box-shadow: 0 1px 2px rgba(0,0,0,.06), 0 10px 24px -16px rgba(0,0,0,.3); transition: transform .5s var(--ax-expo), box-shadow .5s var(--ax-expo), opacity .4s ease; }
html.ax .wall .shape-regular .blog-thumb{ aspect-ratio: auto; height: 260px; }
html.ax .wall .shape-tall .blog-thumb{ aspect-ratio: auto; height: 380px; }
html.ax .wall .shape-feature{ grid-column: span 2; }
html.ax .wall .shape-feature .blog-thumb{ aspect-ratio: auto; height: 380px; }
html.ax .wall .blog-card .ax-pin, .blog-card::before, .blog-card::after, .blog-thumb::before{ display: none !important; }
html.ax .wall .blog-card.wall-in{ animation: axRiseIn .9s var(--ax-expo) backwards; animation-delay: calc(var(--wi, 0) * 90ms); }
@keyframes axRiseIn{ from{ opacity: 0; transform: translateY(40px); } to{ opacity: 1; transform: none; } }
@media (hover:hover) and (pointer:fine){
  html.ax .wall .blog-card:hover, html.ax .wall .blog-card.ax-tilting:hover{ transform: translateY(-5px); --sc: 1; box-shadow: 0 2px 6px rgba(0,0,0,.08), 0 22px 40px -20px rgba(0,0,0,.4); z-index: 2; }
  html.ax .wall .blog-card:hover .blog-thumb{ transform: scale(1.04); }
}
html.ax .wall .blog-card:active{ transform: scale(.985); }
html.ax .wall .blog-card.is-pressing{ transform: scale(.98) !important; }
@media (max-width: 860px){
  html.ax .wall .shape-tall .blog-thumb, html.ax .wall .shape-feature .blog-thumb{ height: 300px; }
  html.ax .wall .shape-regular .blog-thumb{ height: 230px; }
}
@media (max-width: 560px){
  html.ax .wall .shape-tall .blog-thumb, html.ax .wall .shape-feature .blog-thumb{ height: 280px; }
  html.ax .wall .shape-regular .blog-thumb{ height: 240px; }
}
/* no light sweep on book covers */
.pub-row:hover .pub-cover::after{ animation: none !important; }

/* ------------------------------------------------------------------
   12. BRICK WALL — identical portrait cards in running bond
   ------------------------------------------------------------------ */
html.ax .blog-grid.wall:not(.wall-flat){
  grid-template-columns: repeat(var(--cols2, 6), minmax(0, 1fr));
  grid-auto-rows: auto; grid-auto-flow: row; align-items: stretch;
  column-gap: 14px; row-gap: 14px; max-width: 1240px; padding: .5rem 0 2rem;
}
html.ax .blog-grid.wall.wall-flat{ column-gap: 14px; row-gap: 14px; }
html.ax .wall .blog-card, html.ax .wall .skeleton-card{ aspect-ratio: 3 / 4; height: auto; min-height: 0; margin: 0; display: block; align-self: stretch; }
html.ax .wall .skeleton-card{ border: 0; }
html.ax .wall .blog-thumb{ position: absolute; inset: 0; width: 100%; height: 100% !important; aspect-ratio: auto !important; transition: transform 1.2s var(--ax-expo); }
html.ax .wall .blog-thumb::after{ background: linear-gradient(0deg, rgba(0,0,0,.72) 0%, rgba(0,0,0,.28) 42%, rgba(0,0,0,0) 70%); }
html.ax .wall .blog-card-body{ position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 1.2rem 1.25rem 1.3rem; gap: .45rem; flex: none; background: none; }
html.ax .wall .blog-card h3{ color: #fff; font-size: 1.3rem; line-height: 1.22; margin: 0; }
html.ax .wall .blog-meta{ color: rgba(255,255,255,.78); }
html.ax .wall .blog-meta .tag{ background: rgba(255,255,255,.2); color: #fff; }
html.ax .wall .blog-meta .dot{ background: rgba(255,255,255,.6); }
html.ax .wall .blog-card p, html.ax .wall .blog-card .read-more{ display: none; }
html.ax .wall .blog-card:hover h3{ color: #fff; }
@media (max-width: 560px){ html.ax .blog-grid.wall:not(.wall-flat){ column-gap: 12px; row-gap: 12px; } }

/* ------------------------------------------------------------------
   13. PATTERN WALL — landscape+portrait / equal pair / portrait+landscape
   ------------------------------------------------------------------ */
html.ax .blog-grid.wall:not(.wall-flat){
  grid-template-columns: repeat(10, minmax(0, 1fr));
  grid-auto-rows: clamp(380px, 36vw, 520px);
  column-gap: 16px; row-gap: 16px; max-width: 1240px; align-items: stretch;
}
html.ax .blog-grid.wall:not(.wall-flat) .blog-card,
html.ax .blog-grid.wall:not(.wall-flat) .skeleton-card{ aspect-ratio: auto; height: 100%; }
html.ax .wall .blog-card p{
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  flex: none; margin: .1rem 0 0; font-family: 'Cormorant Garamond', serif; font-style: normal;
  font-size: 1.08rem; line-height: 1.4; color: rgba(255,255,255,.86);
}
html.ax .wall .blog-card p:empty{ display: none; }
html.ax .wall .blog-card-body{ padding-top: 4.2rem; background: linear-gradient(0deg, rgba(0,0,0,.66), rgba(0,0,0,0)); }
html.ax .wall .blog-card[data-ar="p"] h3{ font-size: 1.4rem; }
html.ax .wall .blog-card[data-ar="l"] h3{ font-size: 1.55rem; }
@media (max-width: 860px){
  html.ax .blog-grid.wall:not(.wall-flat){ grid-auto-rows: clamp(320px, 46vw, 420px); column-gap: 12px; row-gap: 12px; }
  html.ax .wall .blog-card[data-ar] h3{ font-size: 1.2rem; }
  html.ax .wall .blog-card p{ -webkit-line-clamp: 3; font-size: 1rem; }
}
@media (max-width: 560px){
  html.ax .blog-grid.wall.wall-one:not(.wall-flat){ grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }
  html.ax .blog-grid.wall.wall-one .blog-card[data-ar="l"], html.ax .blog-grid.wall.wall-one .skeleton-card{ aspect-ratio: 3 / 2; height: auto; }
  html.ax .blog-grid.wall.wall-one .blog-card[data-ar="p"]{ aspect-ratio: 3 / 4; height: auto; }
}

/* calm entrance / hover (blog page and home row) */
html.ax .wall .blog-card.wall-in{ animation: axRiseCalm .7s cubic-bezier(.22,.61,.36,1) backwards; animation-delay: calc(var(--wi, 0) * 80ms); }
@keyframes axRiseCalm{ from{ opacity: 0; transform: translateY(20px); } to{ opacity: 1; transform: none; } }
@media (hover:hover) and (pointer:fine){
  html.ax .wall .blog-card:hover, html.ax .wall .blog-card.ax-tilting:hover{ transform: translateY(-4px); box-shadow: 0 16px 30px -20px rgba(0,0,0,.4); }
  html.ax .wall .blog-card:hover .blog-thumb{ transform: scale(1.03); }
}

/* ------------------------------------------------------------------
   14. Reduced motion: the reader is a plain fade
   ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce){
  .reader-overlay-panel{ top: 0 !important; left: 0 !important; width: 100vw !important; height: 100vh !important; border-radius: 0 !important; transition: opacity .3s ease !important; }
}

/* ------------------------------------------------------------------
   15. CARDS — one height, white frame, refined type
   ------------------------------------------------------------------ */
.wall-section{ background: #efefef !important; }
html.ax .wall .blog-card, html.ax .wall .skeleton-card{
  border: 10px solid #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.07), 0 10px 26px -16px rgba(0,0,0,.35);
  background: #fff;
}
html.ax .wall .skeleton-card{ background: linear-gradient(100deg, #e8e8e8 30%, #f4f4f4 50%, #e8e8e8 70%) 0 0 / 200% 100%; animation: shimmer 1.6s ease-in-out infinite !important; }
html.ax .wall .skeleton-card > *{ display: none; }
html.ax .wall .blog-card:focus-visible{ outline: 2px solid #000; outline-offset: 4px; }
html.ax .wall .blog-card-body{ padding: 4.4rem 1.4rem 1.3rem; gap: .5rem; }
html.ax .wall .blog-meta{ font-size: .66rem; letter-spacing: .16em; text-transform: uppercase; gap: .6rem; }
html.ax .wall .blog-meta .tag{ background: #fff; color: #000; padding: .2rem .5rem; font-weight: 500; letter-spacing: .14em; }
html.ax .wall .blog-card h3{ font-weight: 400; letter-spacing: -.005em; line-height: 1.2; }
html.ax .wall .blog-card p{ font-size: 1.08rem; line-height: 1.5; max-width: 40ch; }
html.ax .wall .blog-card .read-more{
  display: inline-flex; align-items: center; gap: .55rem; margin-top: .5rem; font-size: .64rem; letter-spacing: .18em; text-transform: uppercase;
  color: rgba(255,255,255,.85); text-decoration: none;
}
html.ax .wall .blog-card .read-more svg{ width: 12px; height: 12px; transition: transform .5s var(--ax-expo); }
@media (hover:hover){ html.ax .wall .blog-card:hover .read-more svg{ transform: translateX(5px); } }
@media (max-width: 560px){
  html.ax .blog-grid.wall.wall-one .blog-card[data-ar], html.ax .blog-grid.wall.wall-one .skeleton-card{ aspect-ratio: 4 / 5; height: auto; }
}
.filter-tag:focus-visible, .page-btn:focus-visible{ outline: 2px solid #000; outline-offset: 3px; }
.filter-tag, .page-btn{ border-radius: 0; text-transform: uppercase; letter-spacing: .12em; }

/* ------------------------------------------------------------------
   16. POST PAGES / READER polish
   ------------------------------------------------------------------ */
.post-hero .label{ letter-spacing: .2em; font-size: .72rem; }
.post-hero .subtitle{ max-width: 34em; line-height: 1.5; }
.post-meta-row .stat{ letter-spacing: .1em; text-transform: uppercase; font-size: .7rem; }
.post-body{ font-size: 1.34rem; line-height: 1.9; hyphens: manual; }
.post-body p{ margin-bottom: 1.5rem; }
.post-body h2{ margin: 3rem 0 1.1rem; }
.post-body img{ border: 10px solid #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.07), 0 18px 36px -22px rgba(0,0,0,.4); margin: 2.2rem 0; }
.post-body blockquote{ font-size: 1.45rem; line-height: 1.6; }
.related-card, .related-thumb{ border-radius: 0; }
.related-card{ border: 8px solid #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.08), 0 14px 30px -20px rgba(0,0,0,.4); background: #fff; }
.related-body{ padding: 1.1rem 1.1rem 1.3rem; }
.related-tag{ letter-spacing: .16em; text-transform: uppercase; font-size: .64rem; }
.related-card:focus-visible, .like-btn:focus-visible, .share-btn:focus-visible, .cf-submit:focus-visible{ outline: 2px solid #000; outline-offset: 3px; }
.comment-avatar, .cf-mini-avatar{ filter: grayscale(1); }
.comment-item{ padding: 1.6rem 0 .8rem; }
.comment-msg{ line-height: 1.7; }

/* ------------------------------------------------------------------
   17. iOS / WebKit fix — cards must not rely on stretch + aspect-ratio.
   A grid item whose only in-flow content is absolutely positioned (thumb +
   body) and that has aspect-ratio + height:auto + align-self:stretch
   collapses to just its border (20x25px) in WebKit, so the whole wall
   looked empty on iPhone.  With align-self:start the ratio is honoured in
   every engine.  Fixed-row desktop/tablet layouts keep height:100%.
   ------------------------------------------------------------------ */
html.ax .blog-grid.wall.wall-flat .blog-card,
html.ax .blog-grid.wall.wall-one .blog-card,
html.ax .blog-grid.wall.wall-one .skeleton-card{ align-self: start; width: 100%; }
html.ax .blog-grid.wall-broken .blog-card{ opacity: 1 !important; }
