/* =====================================================================
   Glass tile project cards + glass pop-ups (pro mode).
   Ported from prototype/background/sections (cards.css + panel.css) on 2026-10-05 with Ziv's settings:
   glass tile · 16:10 · text under the picture · rim 8px · frost blur 3px (sharp) · back glow + flashlight on hover ·
   light colour = the project's own colour (--a) · on-scroll animation: drop-in with a bounce.
   lib/projects.php writes the attributes on .projects (data-cards=glass …) and the extra card layers; glass.js does the rest.
   ===================================================================== */
.projects[data-cards=glass] .pj-card{--L:var(--a)}

/* ---------- shared: the text plate (name + one line + "view") ---------- */
.pj-plate{display:flex;flex-direction:column;gap:4px;min-width:0;padding:0 2px}
.pj-line,.pj-cta{display:none}
.projects[data-shape=r1610] .pj-art{aspect-ratio:16/10}

/* =====================================================================
   1. GLASS — the photo fills the card; the bottom is frosted glass with the name on it.
      A rim around the photo makes the card look like a thick glass tile (the attached example).
   ===================================================================== */
.projects[data-cards=glass] .pj-card{position:relative;gap:0;padding:var(--rim,8px);border-radius:calc(20px + var(--rim,8px));
  background:rgba(255,255,255,.42);box-shadow:inset 0 0 0 1px rgba(255,255,255,.75),inset 0 1px 0 rgba(255,255,255,.95),0 22px 46px -24px rgba(16,40,80,.45);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
[data-theme=dark] .projects[data-cards=glass] .pj-card{background:rgba(255,255,255,.06);box-shadow:inset 0 0 0 1px rgba(255,255,255,.1),inset 0 1px 0 rgba(255,255,255,.16),0 26px 50px -24px rgba(0,0,0,.8)}
.projects[data-cards=glass] .pj-art{border-radius:20px;box-shadow:none!important;transform:none!important}
.projects[data-cards=glass] .pj-name{padding:0;font:400 clamp(19px,1.8vw,25px)/1.1 var(--f-head);letter-spacing:-.005em}
.projects[data-cards=glass] .pj-line{display:block;font:300 clamp(12.5px,1vw,14px)/1.35 var(--f-body);opacity:.82}
.projects[data-cards=glass] .pj-cta{display:inline-flex;align-self:flex-start;margin-top:8px;padding:8px 14px;border-radius:99px;background:#fff;color:#111;font:600 12.5px/1 var(--f-body);text-shadow:none;
  box-shadow:0 6px 16px -6px rgba(0,0,0,.4);transition:transform .3s}
.projects[data-cards=glass] .pj-gen .pj-wm{display:none}
.projects[data-cards=glass] .pj-card.lit{--lift:-6px}
.projects[data-cards=glass] .pj-card.lit .pj-cta{transform:translateX(3px)}
.projects[data-cards=glass][data-shape=land] .pj-cta,.projects[data-cards=glass][data-shape=r1610] .pj-cta,.projects[data-cards=glass][data-shape=r32] .pj-cta{display:none}
/* text under the picture (data-text=below), like the slabs: the shape is the picture's; the text adds to the card's height */
.projects[data-cards=glass][data-text=below] .pj-plate{position:relative;padding:14px 12px 8px;gap:5px;color:inherit}
.projects[data-cards=glass][data-text=below] .pj-name{font-weight:600;font-size:clamp(16px,1.45vw,20px)}
.projects[data-cards=glass][data-text=below] .pj-line{display:block;font-weight:400;font-size:13px;opacity:.65}
.projects[data-cards=glass][data-text=below] .pj-cta{display:none}

/* =====================================================================
   POSE — every style: lift (when switched on) + mouse tilt / prism angle (cards.js sets --rx --ry --rz)
   ===================================================================== */
.projects[data-cards] .pj-card{/* transform: see the end of the file (it includes the on-scroll animation offset) */
  transition:transform .55s cubic-bezier(.2,.9,.25,1),box-shadow .5s}
.projects[data-cards] .pj-card.tilting{transition:transform .08s linear,box-shadow .2s}
.sx-edges,.sx-glow{display:none}

/* =====================================================================
   EFFECTS — work with every style. Face = the whole card (glass, slabs) or the picture (flat, spectrum, refract).
   ===================================================================== */
/* back glow */
.projects.sx-glowfx[data-face=card] .sx-glow{display:block;position:absolute;inset:0;border-radius:inherit;z-index:-1;pointer-events:none;opacity:0;transition:opacity .6s;
  box-shadow:0 0 0 1.5px var(--L),0 0 40px 2px color-mix(in srgb,var(--L) 70%,transparent),0 30px 64px -14px color-mix(in srgb,var(--L) 85%,transparent)}
.projects.sx-glowfx[data-face=card] .pj-card.lit .sx-glow{opacity:1}
.projects.sx-glowfx[data-face=art] .pj-card.lit .pj-art{box-shadow:0 0 0 2px var(--L),0 0 34px -2px color-mix(in srgb,var(--L) 75%,transparent),0 26px 60px -14px color-mix(in srgb,var(--L) 80%,transparent)!important}
/* effect layers (flash + flashlight) sit on the face */
.sx-fx{position:absolute;inset:0;z-index:5;border-radius:inherit;overflow:hidden;pointer-events:none}
.sx-fx i{position:absolute;inset:-2px;display:block;opacity:0}
/* flash: light sweep (white + light colour) */
.projects[data-flash=sweep] .sx-flash{mix-blend-mode:screen;background-size:260% 100%;background-position:var(--sweep0,120%) 0;
  background-image:linear-gradient(var(--sweepA,105deg),transparent 30%,color-mix(in srgb,var(--L) 55%,transparent) 46%,rgba(255,255,255,.8) 50%,color-mix(in srgb,var(--L) 55%,transparent) 54%,transparent 70%)}
/* flash: rainbow (caustic) */
.projects[data-flash=rainbow] .sx-flash{mix-blend-mode:screen;background-size:250% 100%;background-position:var(--sweep0,120%) 0;
  background-image:linear-gradient(var(--sweepA,105deg),transparent 35%,rgba(255,90,120,.4) 44%,rgba(255,220,80,.45) 47%,rgba(90,240,150,.42) 50%,rgba(60,180,255,.45) 53%,rgba(150,110,255,.4) 56%,transparent 64%)}
/* .flash is added by cards.js every time a card switches on or the mouse enters it (so it also replays with "always on") */
.projects[data-flash=sweep] .pj-card.flash .sx-flash,.projects[data-flash=rainbow] .pj-card.flash .sx-flash{animation:sxSweep 1.15s cubic-bezier(.3,.6,.2,1) both}
/* on a white glass face, "screen" can't brighten white — so there the flash is drawn normally, softer */
:root[data-theme=light] .projects[data-face=card] .sx-flash{mix-blend-mode:normal;filter:saturate(1.3);opacity:0}
@keyframes sxSweep{0%{opacity:1;background-position:var(--sweep0,120%) 0}85%{opacity:1}100%{opacity:0;background-position:var(--sweep1,-20%) 0}}
/* flashlight: a soft spot of light that follows the mouse */
.projects.sx-torch .sx-torch{transition:opacity .35s;mix-blend-mode:soft-light;
  background:radial-gradient(55% 45% at var(--mx,50%) var(--my,30%),rgba(255,255,255,.75),rgba(255,255,255,.18) 45%,transparent 70%)}
.projects.sx-torch .pj-card.hov .sx-torch{opacity:1}
:root[data-theme=light] .projects.sx-torch[data-face=card] .sx-torch{mix-blend-mode:overlay}
@media (prefers-reduced-motion:reduce){.sx-flash{animation:none!important}}

.projects[data-cards=glass] .pj-card.ghost{visibility:hidden}
/* small cards (2 per row on phones / tablets): glass shows only the name */
@media (max-width:700px){
  .projects[data-cards=glass][data-text=in] .pj-line,.projects[data-cards=glass] .pj-cta{display:none}
  .projects[data-cards=glass][data-text=in] .pj-plate{left:calc(var(--rim,8px) + 12px);right:calc(var(--rim,8px) + 10px);bottom:calc(var(--rim,8px) + 12px)}
  .projects[data-cards=glass][data-text=in][data-frost=sharp] .pj-plate{left:min(var(--rim,8px),6px);right:min(var(--rim,8px),6px);bottom:min(var(--rim,8px),6px);padding:10px 12px 11px;border-radius:0 0 13px 13px}
  .projects[data-cards=glass][data-text=below] .pj-line{font-size:12px}
  .projects[data-cards=glass] .pj-name{font-size:16px}
  .projects[data-cards=glass] .pj-card{padding:min(var(--rim,8px),6px);border-radius:18px}
  .projects[data-cards=glass] .pj-art{border-radius:13px}
}

/* =====================================================================
   POP-UPS AS GLASS TILES (html.sx-ppglass, set by cards.js)
   The pop-up = two glass panes inside one glass rim: the picture pane (frosted bottom with the title, like the card)
   and a solid reading pane in the theme's colours. Backdrop = a tinted blur of the page. Close / arrows = glass buttons.
   Colours come from the Projects section (--sxSecL/D, --sxInkL/D, set by panel.js).
   ===================================================================== */
html.sx-ppglass .pp{--pp-bg:color-mix(in srgb,var(--sxSecL,#eef3f9) 40%,#fff);--pp-ink:var(--sxInkL,#14161f);
  --pp-mut:color-mix(in srgb,var(--sxInkL,#14161f) 62%,transparent);--pp-line:color-mix(in srgb,var(--sxInkL,#14161f) 12%,transparent);
  --pp-chip:color-mix(in srgb,var(--sxInkL,#14161f) 6%,transparent);--pp-glass:rgba(255,255,255,.4);--pp-hi:rgba(255,255,255,.85)}
html.sx-ppglass[data-theme=dark] .pp{--pp-bg:color-mix(in srgb,var(--sxSecD,#0c1120) 90%,#fff);--pp-ink:var(--sxInkD,#eef1f8);
  --pp-mut:color-mix(in srgb,var(--sxInkD,#eef1f8) 64%,transparent);--pp-line:color-mix(in srgb,var(--sxInkD,#eef1f8) 12%,transparent);
  --pp-chip:color-mix(in srgb,var(--sxInkD,#eef1f8) 7%,transparent);--pp-glass:rgba(255,255,255,.07);--pp-hi:rgba(255,255,255,.16)}
html.sx-ppglass .pp-bk{background:color-mix(in srgb,var(--sxSecL,#eef3f9) 38%,transparent);-webkit-backdrop-filter:blur(18px) saturate(1.3);backdrop-filter:blur(18px) saturate(1.3)}
html.sx-ppglass[data-theme=dark] .pp-bk{background:color-mix(in srgb,var(--sxSecD,#0c1120) 62%,transparent)}
html.sx-ppglass .pp-dl{padding:var(--ppRim,8px);border-radius:calc(22px + var(--ppRim,8px));background:var(--pp-glass);overflow:visible;
  -webkit-backdrop-filter:blur(16px) saturate(1.2);backdrop-filter:blur(16px) saturate(1.2);
  box-shadow:inset 0 0 0 1px var(--pp-hi),inset 0 1px 0 var(--pp-hi),0 40px 90px -30px rgba(10,30,70,.5)}
html.sx-ppglass[data-theme=dark] .pp-dl{box-shadow:inset 0 0 0 1px var(--pp-hi),inset 0 1px 0 var(--pp-hi),0 40px 90px -24px rgba(0,0,0,.85)}
/* picture pane: the photo with a frosted bottom and the title on the glass (white type) */
html.sx-ppglass .pp-hero{border-radius:22px;isolation:isolate}
html.sx-ppglass .pp-hero::after{-webkit-backdrop-filter:blur(var(--gblurP,16px)) saturate(1.25);backdrop-filter:blur(var(--gblurP,16px)) saturate(1.25);
  -webkit-mask-image:linear-gradient(transparent 38%,#000 70%);mask-image:linear-gradient(transparent 38%,#000 70%);
  background:linear-gradient(180deg,transparent 30%,color-mix(in srgb,var(--a) 22%,rgba(8,14,26,.42)) 100%)}
html.sx-ppglass .pp-cap{color:#fff;text-shadow:0 1px 10px rgba(0,0,0,.28)}
html.sx-ppglass .pp-cap h2{font-weight:500;letter-spacing:-.02em}
html.sx-ppglass .pp-kick{color:rgba(255,255,255,.82)}
html.sx-ppglass .pp-meta .pj-badge.tag{background:rgba(255,255,255,.18);color:#fff;box-shadow:inset 0 0 0 1px rgba(255,255,255,.35);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
html.sx-ppglass .pp-btn{border-radius:99px;text-shadow:none}
html.sx-ppglass .pp-btn.pri{background:#fff;color:#111;box-shadow:0 8px 20px -8px rgba(0,0,0,.45)}
html.sx-ppglass .pp-btn.sec{background:rgba(255,255,255,.18);color:#fff;box-shadow:inset 0 0 0 1px rgba(255,255,255,.45);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
/* reading pane: solid (easy to read), its own rounded glass-edged sheet under the picture */
html.sx-ppglass .pp-body{margin-top:var(--ppRim,8px);background:var(--pp-bg);border-radius:22px;padding-top:30px;
  box-shadow:inset 0 0 0 1px var(--pp-hi)}
html.sx-ppglass .pp-dl > .pp-body:first-child{margin-top:0}
html.sx-ppglass .pp-card{background:color-mix(in srgb,var(--a) 6%,var(--pp-bg));border-color:color-mix(in srgb,var(--a) 18%,transparent);border-radius:14px;
  box-shadow:inset 0 1px 0 var(--pp-hi)}
/* glass buttons: close + arrows */
html.sx-ppglass .pp-x,html.sx-ppglass .pp-nav{background:rgba(255,255,255,.55);color:#111;box-shadow:inset 0 0 0 1px rgba(255,255,255,.9),0 8px 22px -8px rgba(10,30,70,.4);
  -webkit-backdrop-filter:blur(10px) saturate(1.3);backdrop-filter:blur(10px) saturate(1.3)}
html.sx-ppglass[data-theme=dark] .pp-x,html.sx-ppglass[data-theme=dark] .pp-nav{background:rgba(14,18,30,.55);color:#fff;box-shadow:inset 0 0 0 1px rgba(255,255,255,.2),0 8px 22px -8px rgba(0,0,0,.6)}
html.sx-ppglass .pp-x:hover,html.sx-ppglass .pp-nav:hover{background:#fff;color:#111}
/* the card's effects carry into the pop-up: flash across the picture when it opens, flashlight, back glow */
html.sx-ppglass .pp-hero .sx-fx{z-index:3;border-radius:inherit}
html.sx-ppglass .pp-dl.sx-glow-on{box-shadow:inset 0 0 0 1px var(--pp-hi),0 0 0 1.5px color-mix(in srgb,var(--L) 70%,transparent),0 0 60px 4px color-mix(in srgb,var(--L) 45%,transparent),0 40px 90px -30px rgba(10,30,70,.5)}
.pp .pp-hero.flash .sx-flash{animation:sxSweep 1.3s .25s cubic-bezier(.3,.6,.2,1) both}
.pp.sx-torch-on .pp-hero:hover .sx-torch{opacity:1}
.pp .sx-torch{transition:opacity .35s;mix-blend-mode:soft-light;background:radial-gradient(45% 55% at var(--mx,50%) var(--my,30%),rgba(255,255,255,.7),rgba(255,255,255,.15) 45%,transparent 70%)}
.pp[data-flash=sweep] .sx-flash{mix-blend-mode:screen;background-size:260% 100%;background-position:var(--sweep0,120%) 0;
  background-image:linear-gradient(var(--sweepA,105deg),transparent 30%,color-mix(in srgb,var(--L) 55%,transparent) 46%,rgba(255,255,255,.8) 50%,color-mix(in srgb,var(--L) 55%,transparent) 54%,transparent 70%)}
.pp[data-flash=rainbow] .sx-flash{mix-blend-mode:screen;background-size:250% 100%;background-position:var(--sweep0,120%) 0;
  background-image:linear-gradient(var(--sweepA,105deg),transparent 35%,rgba(255,90,120,.4) 44%,rgba(255,220,80,.45) 47%,rgba(90,240,150,.42) 50%,rgba(60,180,255,.45) 53%,rgba(150,110,255,.4) 56%,transparent 64%)}
@media (max-width:700px){
  html.sx-ppglass .pp-dl{padding:0;border-radius:0;-webkit-backdrop-filter:none;backdrop-filter:none;background:var(--pp-bg)}
  html.sx-ppglass .pp-hero{border-radius:0}
  html.sx-ppglass .pp-body{margin-top:0;border-radius:0;box-shadow:none}
}

/* pop-up picture pane with the sharp frost edge: the caption itself is the frosted glass band */
html.sx-ppglass.sx-frost-sharp .pp-hero::after{display:none}
html.sx-ppglass.sx-frost-sharp .pp-cap{left:0;right:0;bottom:0;padding:22px 40px 24px;
  -webkit-backdrop-filter:blur(var(--gblurP,16px)) saturate(1.3);backdrop-filter:blur(var(--gblurP,16px)) saturate(1.3);
  background:color-mix(in srgb,var(--a) 16%,rgba(8,14,26,.22));box-shadow:inset 0 1px 0 rgba(255,255,255,.45)}
@media (max-width:700px){html.sx-ppglass.sx-frost-sharp .pp-cap{padding:16px 18px 18px}}

/* on-scroll animation: drop in with a bounce (glass.js adds .ra + data-ra, then .ra-in when it scrolls into view) */
.projects .ra:not(.ra-in){opacity:0}
.projects .pj-head > .ra[data-ra=drop]:not(.ra-in){transform:translateY(calc(var(--rdist,40px) * -1.5))}
.projects .ra.ra-run{transition:opacity var(--rdur,.8s) ease,transform var(--rdur,.8s) var(--rease,cubic-bezier(.2,.8,.2,1))!important;
  transition-delay:calc(var(--ri,0) * var(--rstag,90ms))!important}
.projects .ra[data-ra=drop].ra-run{--rease:cubic-bezier(.3,1.5,.5,1)}

/* on-scroll animation (glass.js .ra) for cards: the cards already use transform for lift / tilt, so the animation's
   offset goes in front of it (--raT) instead of replacing it */
.projects[data-cards] .pj-card{transform:var(--raT,translate(0)) perspective(var(--persp,1100px)) translateY(var(--lift,0px)) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) rotateZ(var(--rz,0deg))}
.projects .pj-card.ra[data-ra=drop]:not(.ra-in){--raT:translateY(calc(var(--rdist,40px) * -1.5))}

/* ---------- card + pop-up layout (lab round 6, 2026-10-04) ---------- */
/* cards: no description line under the title (any style) */
.projects .pj-line{display:none!important}
/* pop-ups: no kicker above the title (e.g. "Database") */
.pp .pp-kick{display:none}
/* pop-ups: long pictures never wider than the reading pane */
html.sx-ppglass .pp-body{overflow:clip}
.pp-body img,.pp-body video,.pp-body svg,.pp-body canvas{max-width:100%}
.pp-body img{height:auto}
/* pop-up caption: title + badges on the left. The project's link (button, and the address under it when it is another
   website) sits at the right, on the line above the badges. It is absolutely placed, so it doesn't make the caption taller. */
.pp .pp-cap{--capPadX:0px;--capPadB:0px;--metaH:22px}
.pp .pp-cap h2{margin-bottom:10px}
.pp .pp-cap:has(.pp-acts) h2{padding-right:230px}
.pp .pp-acts{position:absolute;right:var(--capPadX);bottom:calc(var(--capPadB) + var(--metaH) + 10px);margin:0;justify-content:flex-end}
html.sx-ppglass.sx-frost-sharp .pp-cap{--capPadX:40px;--capPadB:24px}
.pp .pp-url{color:inherit}
@media (max-width:700px){
  .pp .pp-cap:has(.pp-acts) h2{padding-right:0}
  .pp .pp-acts{position:static;margin-top:12px;justify-content:flex-start}
  .pp .pp-link{align-items:flex-start}
}
/* sharp frosted caption: on hover it becomes more opaque so the text stands out */
html.sx-ppglass.sx-frost-sharp .pp-cap{transition:background .35s,-webkit-backdrop-filter .35s,backdrop-filter .35s}
html.sx-ppglass.sx-frost-sharp .pp-cap:hover{background:color-mix(in srgb,var(--a) 18%,rgba(8,14,26,.46));
  -webkit-backdrop-filter:blur(calc(var(--gblurP,16px) * 1.6)) saturate(1.3);backdrop-filter:blur(calc(var(--gblurP,16px) * 1.6)) saturate(1.3)}
html.sx-ppglass:not(.sx-frost-sharp) .pp-hero::after{transition:opacity .35s}
html.sx-ppglass:not(.sx-frost-sharp) .pp-cap:hover{text-shadow:0 1px 14px rgba(0,0,0,.55)}
/* no flashlight on the pop-up picture */
.pp .sx-torch{display:none}
