/* ============================================================
   THEME TRAITS — omidizadiart.com
   Everything a preset can change beyond colour: button shape,
   how things separate, surface texture, how art is framed,
   wallpaper, and click effects.

   These hook onto the REAL site's existing classes (.btn, .frame,
   .stripe, .section) so a preset restyles the whole page.
   Loaded after style.css so it wins where they overlap.
   ============================================================ */

/* ══════════ SURFACES ══════════ */
html.tex-paper body {
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.05'/%3E%3C/svg%3E");
}
html.tex-canvas body {
  background-image:
    repeating-linear-gradient(90deg, rgba(0,0,0,.028) 0 1px, transparent 1px 3px),
    repeating-linear-gradient(0deg,  rgba(0,0,0,.028) 0 1px, transparent 1px 3px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='1.1' numOctaves='2'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='.06'/%3E%3C/svg%3E");
}
html.tex-tile body::before {
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background-image:url("../patterns/girih-star.jpg");
  background-size:340px; opacity:.06; mix-blend-mode:overlay;
}
html.tex-wash body::before {
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none; opacity:.45;
  background:
    radial-gradient(ellipse 60% 40% at 15% 20%, color-mix(in srgb, var(--red) 24%, transparent), transparent 70%),
    radial-gradient(ellipse 50% 45% at 85% 70%, color-mix(in srgb, var(--green) 24%, transparent), transparent 70%);
}

/* ══════════ SOFTENED EDGES ══════════
   A small radius, not a rounded-rect card. Enough to take the
   90-degree bite off every corner while still reading as a frame.
   Tune the two numbers here and everything follows. */
:root { --radius: 7px; --radius-lg: 16px; --radius-inner: 5px; }

.vid-card .vwrap, .portrait-stack, .art-in,
.lb-img, .lb-rail, .cell, .grid-cell,
input, textarea, select, .field input, .field textarea, .field select {
  border-radius: var(--radius);
}
.btn, .nav-cta, .chip { border-radius: var(--radius); }

/* A frame is the biggest box on the page, so it carries the biggest
   curve. The picture inside a mat takes a smaller one: nested radii
   have to shrink inward or the corner reads as two fighting arcs. */
.frame { border-radius: var(--radius-lg); overflow: hidden; }
.frame img, .frame .art-in, .frame .portrait-stack { border-radius: var(--radius-inner); }
html.frm-mat .frame img { border-radius: var(--radius-inner); }
html.frm-none .frame, html.frm-none .frame img { border-radius: 0; overflow: visible; }

/* ══════════ WALLPAPER ══════════
   A mask over a coloured layer, so the tile always takes the
   direction's own gold instead of being baked to one colour. */
.wallpaper {
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background:var(--gold);
  -webkit-mask:var(--wall) 0 0/var(--wall-size,110px) repeat;
          mask:var(--wall) 0 0/var(--wall-size,110px) repeat;
  opacity:var(--wall-op,0);
  transition:opacity .55s var(--ease), background .55s var(--ease);
}

/* The alternating rhythm is kept: some sections show the wallpaper,
   the dark bands cover it. The only thing changed is the JOIN. The
   band's ground is fully opaque through the middle and ramps to
   transparent over 170px at each end, so the wallpaper fades out
   and back in rather than stopping at a ruled line. */
html.wall-on body     { background: var(--bg); }
html.wall-on .section { background: transparent; }

html.wall-on .dark {
  border-top-color: transparent; border-bottom-color: transparent;
  background: linear-gradient(
    to bottom,
    transparent 0,
    var(--bg-2) 170px,
    var(--bg-2) calc(100% - 170px),
    transparent 100%);
}
/* one pattern at a time — the built-in girih would fight the wallpaper */
html.wall-on .dark.girih { background-image: none; }

/* The hero covered its top 45% with solid ground, which killed the
   wallpaper for the whole first screen — the page opened looking as
   if there were no pattern at all. Now only a short solid cap sits
   behind the nav for legibility, fading out by a third of the way
   down, so the pattern is present from the first screen onward. */
html.wall-on .hero {
  background: radial-gradient(ellipse at 12% 40%, color-mix(in srgb, var(--gold) 7%, transparent), transparent 60%),
              linear-gradient(to bottom,
                var(--bg) 0,
                color-mix(in srgb, var(--bg) 72%, transparent) 14%,
                transparent 38%);
}

/* ══════════ BUTTONS ══════════
   Every button-shaped thing on the site follows the chosen shape,
   not just .btn. Previously the nav CTA and the collection filter
   chips kept their rectangles while the hero buttons changed, which
   read as a bug. The lightbox arrows and the video play button stay
   circular on purpose; a brush stroke on a 44px circle is illegible. */
.btn, .nav-cta, .chip {
  transition:.3s var(--ease);
  /* text must never spill past its own shape */
  white-space:nowrap;
  line-height:1.15;
  display:inline-flex; align-items:center; justify-content:center;
}

/* .inquire-link is the quiet button under each Iranian Series piece.
   It is a line of type with a rule under it, so it takes the chosen
   style as its UNDERLINE rather than growing a box around itself. */
html.btn-ink .inquire-link {
  border-bottom:0; position:relative; padding-bottom:12px;
}
html.btn-ink .inquire-link::before {
  content:""; position:absolute; left:-8px; right:-8px; bottom:0; height:9px;
  background:var(--gold);
  -webkit-mask:url("../brushes/brush-sweep.png") center/100% 100% no-repeat;
          mask:url("../brushes/brush-sweep.png") center/100% 100% no-repeat;
  transition:background .3s var(--ease);
}
html.btn-ink .inquire-link:hover::before { background:var(--red); }
html.btn-stamp .inquire-link,
html.btn-rule  .inquire-link { border-bottom:3px solid var(--gold); }
html.btn-arch  .inquire-link { border-bottom:1px solid var(--gold); border-radius:0 0 var(--radius) var(--radius); }
/* the nav CTA sits in a tight bar, so let it shrink rather than clip */
.nav-cta { flex:0 0 auto; }
@media (max-width:1180px){ .nav-cta { padding-left:14px; padding-right:14px; letter-spacing:.12em; } }

/* arched — a mihrab opening rather than a rectangle. The curve eats
   into the top, so the label needs headroom or it rides the arch. */
html.btn-arch .btn,
html.btn-arch .nav-cta,
html.btn-arch .chip {
  border-radius:44% 44% var(--radius) var(--radius) / 34% 34% var(--radius) var(--radius);
}
html.btn-arch .btn      { padding-top:24px; padding-bottom:16px; }
html.btn-arch .nav-cta  { padding-top:16px; padding-bottom:10px; }
html.btn-arch .chip     { padding-top:14px; padding-bottom:9px; }

/* underline — type with a heavy rule, no box */
html.btn-rule .btn,
html.btn-rule .nav-cta,
html.btn-rule .chip {
  border:0; border-bottom:3px solid var(--ink); border-radius:0;
  background:none; color:var(--ink); letter-spacing:.14em;
}
html.btn-rule .btn { padding:9px 2px; }
html.btn-rule .nav-cta, html.btn-rule .chip { padding:7px 2px; }
html.btn-rule .btn.solid, html.btn-rule .chip.on { border-bottom-color:var(--gold); background:none; color:var(--ink); }
html.btn-rule .btn:hover, html.btn-rule .nav-cta:hover, html.btn-rule .chip:hover {
  background:none; color:var(--gold-bright); border-bottom-color:var(--gold-bright);
}

/* letterpress — hard offset shadow */
html.btn-stamp .btn,
html.btn-stamp .nav-cta,
html.btn-stamp .chip { border:1.5px solid var(--ink); box-shadow:4px 4px 0 var(--ink); transition:.14s; }
html.btn-stamp .btn.solid, html.btn-stamp .chip.on { box-shadow:4px 4px 0 var(--gold-2); }
html.btn-stamp .btn:hover,
html.btn-stamp .nav-cta:hover,
html.btn-stamp .chip:hover { transform:translate(3px,3px); box-shadow:1px 1px 0 var(--ink); }

/* brush — the button IS a painted stroke. A generated PNG masks a
   coloured layer behind the label, so the silhouette is real
   brushwork while the colour still comes from the theme.
   The stroke deliberately overhangs the box, so the label keeps its
   own padding and always sits well inside the paint. */
html.btn-ink .btn,
html.btn-ink .nav-cta,
html.btn-ink .chip {
  border:0; background:none; color:var(--ink); border-radius:0;
  position:relative; isolation:isolate;
}
html.btn-ink .btn     { padding:19px 44px; }
html.btn-ink .nav-cta { padding:13px 26px; }
html.btn-ink .chip    { padding:11px 22px; }

html.btn-ink .btn::before,
html.btn-ink .nav-cta::before,
html.btn-ink .chip::before {
  content:""; position:absolute; inset:-10px -18px; z-index:-1;
  background:var(--gold);
  -webkit-mask:var(--brush, url("../brushes/brush-flat.png")) center/100% 100% no-repeat;
          mask:var(--brush, url("../brushes/brush-flat.png")) center/100% 100% no-repeat;
  transition:background .3s var(--ease), transform .35s var(--ease);
}
html.btn-ink .nav-cta::before { inset:-7px -12px; }
html.btn-ink .chip::before    { inset:-6px -12px; opacity:.55; }
html.btn-ink .chip.on::before { opacity:1; }

/* Text on a gold plate must use --on-gold, which flips per theme.
   It was left as --ink, which is fine on the dark themes and
   unreadable on the light ones — dark text on dark amber. */
html.btn-ink .btn,
html.btn-ink .nav-cta { color:var(--on-gold); }
html.btn-ink .chip.on { color:var(--on-gold); }
html.btn-ink .btn.solid { color:var(--bg); }
html.btn-ink .btn.solid::before { background:var(--ink); }
html.btn-ink .btn:hover,
html.btn-ink .nav-cta:hover,
html.btn-ink .chip:hover { transform:translateY(-2px) rotate(-.4deg); background:none; color:var(--on-gold); }
html.btn-ink .btn:hover::before,
html.btn-ink .nav-cta:hover::before,
html.btn-ink .chip:hover::before { background:var(--red); transform:scale(1.03,1.08); }

/* The rest of the nav joins in: each link carries a brush underline
   that paints itself in on hover, so the whole bar speaks the same
   language as the CTA instead of only COMMISSIONS being painted. */
html.btn-ink .nav-links a:not(.nav-cta) {
  position:relative; border-bottom:0; padding-bottom:8px;
}
html.btn-ink .nav-links a:not(.nav-cta)::after {
  content:""; position:absolute; left:-4px; right:-4px; bottom:0; height:7px;
  background:var(--gold);
  -webkit-mask:url("../brushes/brush-sweep.png") center/100% 100% no-repeat;
          mask:url("../brushes/brush-sweep.png") center/100% 100% no-repeat;
  transform:scaleX(0); transform-origin:left center;
  transition:transform .35s var(--ease);
}
html.btn-ink .nav-links a:not(.nav-cta):hover::after { transform:scaleX(1); }

/* A dry or double stroke crumbles into noise on a small control, so
   anything below hero-button size swaps to the loaded stroke — same
   family, same painted edge, but solid enough to hold a label. The
   hero buttons keep whatever stroke was chosen in the customizer. */
html.btn-ink .nav-cta::before,
html.btn-ink .chip::before,
html.btn-ink .inquire-link::before {
  -webkit-mask-image:url("../brushes/brush-loaded.png");
          mask-image:url("../brushes/brush-loaded.png");
}
/* a drier second pass smudged underneath — real paint is layered */
html.btn-ink .btn.solid::after {
  content:""; position:absolute; inset:-13px -24px; z-index:-2; opacity:.3;
  background:var(--gold);
  -webkit-mask:url("../brushes/brush-dry.png") center/100% 100% no-repeat;
          mask:url("../brushes/brush-dry.png") center/100% 100% no-repeat;
  transform:rotate(-.6deg);
}

/* Lightbox controls and the video play button get the brush too, so
   nothing on the page is left as a plain rectangle or circle when
   Brush is chosen. Their strokes are scaled to the control. */
html.btn-ink .lb-x,
html.btn-ink .lb-prev,
html.btn-ink .lb-next,
html.btn-ink .vid-card .play span {
  border:0; background:none; color:var(--ink);
  isolation:isolate;
  /* NB: no `position` here — the lightbox controls are anchored
     absolute inside .lb-img (see LIGHTBOX CONTROLS above), and this
     higher-specificity selector must not undo that. */
}
html.btn-ink .vid-card .play span { position:relative; }
html.btn-ink .lb-x::before,
html.btn-ink .lb-prev::before,
html.btn-ink .lb-next::before,
html.btn-ink .vid-card .play span::before {
  content:""; position:absolute; inset:-6px -10px; z-index:-1;
  background:var(--gold);
  -webkit-mask:var(--brush, url("../brushes/brush-loaded.png")) center/100% 100% no-repeat;
          mask:var(--brush, url("../brushes/brush-loaded.png")) center/100% 100% no-repeat;
  transition:background .3s var(--ease);
}
html.btn-ink .lb-x:hover::before,
html.btn-ink .lb-prev:hover::before,
html.btn-ink .lb-next:hover::before,
html.btn-ink .vid-card .play:hover span::before { background:var(--red); }

/* every other direction keeps these controls round */
html:not(.btn-ink) .lb-x,
html:not(.btn-ink) .lb-prev,
html:not(.btn-ink) .lb-next,
html:not(.btn-ink) .vid-card .play span { border-radius:50%; }

/* ══════════ SHADOWS ══════════
   Dark brown rather than neutral black, and layered so the falloff is
   gradual. A single shadow with a negative spread has a visible edge;
   four stacked at increasing blur fade out with none.

   The selectors below deliberately mirror the two-class ones in
   style.css (.ir-art .frame and friends). A plain .frame is less
   specific and was being overridden. */
:root {
  --shadow-soft:
    0 2px 6px    rgba(var(--shadow), .10),
    0 8px 20px   rgba(var(--shadow), .13),
    0 22px 48px  rgba(var(--shadow), .16),
    0 48px 96px  rgba(var(--shadow), .18);
  --shadow-lift:
    0 3px 8px    rgba(var(--shadow), .12),
    0 12px 28px  rgba(var(--shadow), .16),
    0 30px 64px  rgba(var(--shadow), .20),
    0 64px 120px rgba(var(--shadow), .22);
}

.ir-art .frame, .about-art .frame, .commission-art .frame,
.anthro-card, .lb-img img, .vid-card .vwrap,
.cell, .portrait-stack, .hero-art img, .frame {
  box-shadow: var(--shadow-soft);
}
.anthro-card:hover, .cell:hover, .ir-art .frame:hover { box-shadow: var(--shadow-lift); }

/* The anthro strip scrolls horizontally, and a scroll container CLIPS
   its children's shadows at its own box — overflow-x:auto forces
   vertical clipping too, that is just how CSS works. So two things:
   the scroller gets generous internal padding on every side (handed
   back to the layout with negative margins), and the cards inside it
   carry a TIGHTER shadow whose farthest layer stays well inside that
   padding. A shadow that outreaches its room will always band. */
.anthro-scroller {
  padding: 12px 32px 96px !important;
  margin: 0 -32px -56px;
}
.anthro-card, .anthro-scroller .anthro-card {
  box-shadow:
    0 2px 5px   rgba(var(--shadow), .12),
    0 8px 16px  rgba(var(--shadow), .14),
    0 18px 34px rgba(var(--shadow), .16);
}
.anthro-card:hover, .anthro-scroller .anthro-card:hover {
  box-shadow:
    0 3px 7px   rgba(var(--shadow), .14),
    0 12px 22px rgba(var(--shadow), .17),
    0 24px 44px rgba(var(--shadow), .20);
  }

/* Rounded corners for the polaroid cards — they were missing from the
   radius group, so they snapped back to sharp while everything else
   softened. overflow:hidden lets the artwork share the curve. */
:root { --radius-card: 12px; }
.anthro-card { border-radius: var(--radius-card); overflow: hidden; }
.anthro-card .ph { border-radius: 0; }

html.frm-none .frame, html.frm-none .frame:hover,
html.frm-none .ir-art .frame, html.frm-none .about-art .frame { box-shadow:none; }

/* ══════════ SOCIAL LINKS ══════════ */
.nav-soc {
  display:inline-flex; align-items:center;
  color: var(--ink-soft); transition:.3s;
  padding: 6px 2px;
}
.nav-soc svg { width:18px; height:18px; }
.nav-soc:hover { color: var(--gold-bright); }
.m-soc {
  display:flex; gap:26px; padding:16px 0 4px;
}
.m-soc a {
  display:inline-flex; align-items:center; gap:9px;
  font-family:var(--sans); font-size:12px; font-weight:600; letter-spacing:.16em;
  text-transform:uppercase; text-decoration:none; color:var(--ink-soft);
  border:0 !important; padding:0 !important;
}
.m-soc a svg { width:17px; height:17px; }
.m-soc a:hover { color:var(--gold-bright); }

/* ══════════ FLOATING SECTION MENU ══════════
   The burger is reparented to <body> by main.js and floats top-right
   as a chip. Phones: always visible. Desktop: appears only while the
   nav bar is hidden (html.nav-hidden) or the menu is open, so it
   never doubles the bar's own links. The menu itself is a fixed
   dropdown that works at every size and while scrolled anywhere. */
.nav-burger {
  display: flex !important; flex-direction: column; gap: 5px;
  position: fixed; top: 15px; right: 16px; z-index: 300;
  padding: 12px 11px; cursor: pointer; border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  transition: opacity .3s var(--ease);
}
.nav-burger i { width: 22px; height: 1.5px; background: var(--ink); transition: .3s; }
@media (min-width: 921px) {
  .nav-burger { opacity: 0; pointer-events: none; }
  html.nav-hidden .nav-burger, body.menu-open .nav-burger { opacity: 1; pointer-events: auto; }
}
body.menu-open .nav-burger i:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
body.menu-open .nav-burger i:nth-child(2) { opacity: 0; }
body.menu-open .nav-burger i:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.m-menu {
  display: none; flex-direction: column;
  position: fixed; top: 68px; right: 16px; z-index: 299;
  width: min(300px, calc(100vw - 32px));
  background: var(--bg-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
  padding: 8px 22px 14px;
}
body.menu-open .m-menu { display: flex !important; }
.m-menu a {
  font-family: var(--sans); font-size: 13px; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; text-decoration: none; color: var(--ink);
  padding: 14px 0; border-bottom: 1px solid var(--line-soft);
}
.m-menu a:last-child { border-bottom: 0; }
.m-menu a:hover { color: var(--gold-bright); }

/* ══════════ HERO CLEARANCE ══════════
   The fixed nav is 72px tall and the hero painting ran underneath
   it, hiding the girl's face behind the bar on load — on phones too,
   where the art column moves to the very top. One margin clears it
   in both layouts. */
.hero-art { margin-top: 73px; }  /* 72px bar + its 1px border */

/* ══════════ LIGHTBOX CONTROLS ══════════
   Close / prev / next are reparented into .lb-img by main.js, so
   they anchor to the IMAGE, not the viewport. The old viewport math
   put Next over the side rail on desktop and stranded buttons on
   phones. Anchored to the image, they are right everywhere. */
.lb-img { position: relative; }
.lb-x, .lb-prev, .lb-next {
  position: absolute; z-index: 6; margin: 0;
}
.lb-x    { top: 76px;  right: 26px; left: auto; bottom: auto; transform: none; }
.lb-prev { left: 26px;  top: 50%;   bottom: auto; transform: translateY(-50%); }
.lb-next { right: 26px; top: 50%;   bottom: auto; left: auto; transform: translateY(-50%); }
@media (min-width: 1081px) {
  .lb-x { top: 22px; }
}

/* ══════════ INSTAGRAM-STYLE GRID ON PHONES ══════════
   On a phone the collection becomes a tight three-across thumbnail
   wall — small squares, hairline gaps, no hover veil — so all 49
   works can be flicked through in seconds. Tapping any square still
   opens the full lightbox with title and statement. */
@media (max-width: 640px) {
  .grid { grid-template-columns: repeat(3, 1fr); gap: 2px; }
  .cell, .cell.wide { grid-column: auto; aspect-ratio: 1 / 1; border-radius: 2px; }
  .cell .veil { display: none; }
  .cell { box-shadow: none; }
}

/* ══════════ STILL IMAGES ══════════
   The collection grid used a slow Ken Burns drift on every cell.
   Forty-nine paintings all creeping at once is genuinely nauseating,
   so it is off everywhere, not merely under reduced-motion. */
.cell img, .hero-art img {
  animation: none !important;
  transform: none !important;
}

/* ══════════ CAPTIONS OVER ARTWORK ══════════
   The veil is a dark scrim by definition, so its text has to stay
   light in EVERY direction. It was using --ink, which flips dark on
   the cream and beige grounds and vanished into the painting. */
.cell .veil {
  background: linear-gradient(180deg,
    transparent 30%,
    rgba(12,9,6,.55) 62%,
    rgba(12,9,6,.92) 100%);
}
.cell .veil .t {
  color:#F6EEDD;
  text-shadow:0 1px 3px rgba(0,0,0,.65), 0 0 18px rgba(0,0,0,.4);
}
.cell .veil .m {
  color: color-mix(in srgb, var(--gold) 45%, #FFF3D4);
  text-shadow:0 1px 3px rgba(0,0,0,.7);
}
/* same rule for the caption sitting on the hero painting */
.hero-art .caption {
  color:#F6EEDD;
  text-shadow:0 1px 3px rgba(0,0,0,.65);
}

/* ══════════ SEPARATORS ══════════
   The kicker stripe is the site's recurring rule motif. */
html.rule-double .stripe { height:auto; border-top:3px solid var(--line-strong); border-bottom:1px solid var(--line-strong); }
html.rule-double .stripe i { display:none; }
html.rule-orn .stripe { border-top:1px solid var(--gold); border-bottom:1px solid var(--gold); height:9px; }
html.rule-orn .stripe i { display:none; }
html.rule-brush .stripe {
  height:8px; background:var(--gold);
  clip-path:polygon(0 40%,12% 10%,30% 55%,48% 15%,66% 60%,84% 20%,100% 45%,100% 80%,0 90%);
}
html.rule-brush .stripe i { display:none; }
html.rule-tile .stripe {
  height:13px; width:64px;
  background:var(--band, url("../patterns/band-kilim.png")) repeat-x;
  background-size:auto 100%;
}
html.rule-tile .stripe i { display:none; }

/* ══════════ ART FRAMES ══════════ */
html.frm-mat .frame { background:var(--bg-3); padding:clamp(18px,2.4vw,38px); border:0; }
html.frm-mat .frame img { box-shadow:0 0 0 1px var(--line), 0 2px 10px rgba(var(--shadow),.2); }

html.frm-none .frame { padding:0; background:none; border:0; box-shadow:none; }

html.frm-tape .frame { padding:14px; background:var(--bg-3); transform:rotate(-.5deg); position:relative; }
html.frm-tape .frame::before, html.frm-tape .frame::after {
  content:""; position:absolute; width:52px; height:19px; z-index:4;
  background:color-mix(in srgb, var(--gold) 34%, transparent);
  border:1px solid color-mix(in srgb, var(--gold) 45%, transparent);
}
html.frm-tape .frame::before { top:-9px; left:-14px; transform:rotate(-38deg); }
html.frm-tape .frame::after  { bottom:-9px; right:-14px; transform:rotate(-38deg); }

/* ══════════ CLICK EFFECTS ══════════ */
.fx-layer { position:fixed; inset:0; z-index:2000; pointer-events:none; overflow:hidden; }

.fx-ripple {
  position:absolute; border-radius:50%; border:1.5px solid var(--gold);
  transform:translate(-50%,-50%) scale(0);
  animation:fxRipple 720ms cubic-bezier(.16,.7,.3,1) forwards;
}
@keyframes fxRipple {
  0%{transform:translate(-50%,-50%) scale(0);opacity:.9;border-width:2.5px}
  100%{transform:translate(-50%,-50%) scale(1);opacity:0;border-width:.5px}
}

.fx-dust {
  position:absolute; width:var(--s); height:var(--s); border-radius:50%;
  background:radial-gradient(circle at 35% 35%, var(--gold-bright), var(--gold) 55%, transparent 72%);
  transform:translate(-50%,-50%);
  animation:fxDust var(--d) cubic-bezier(.2,.6,.35,1) forwards;
}
@keyframes fxDust {
  0%{opacity:0;transform:translate(-50%,-50%) translate(0,0) scale(.2)}
  12%{opacity:1}
  100%{opacity:0;transform:translate(-50%,-50%) translate(var(--dx),var(--dy)) scale(var(--sc))}
}

.fx-star {
  position:absolute; width:var(--s); height:var(--s); background:var(--gold-bright);
  transform:translate(-50%,-50%);
  clip-path:polygon(50% 0%,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%);
  animation:fxStar var(--d) cubic-bezier(.18,.7,.3,1) forwards;
}
@keyframes fxStar {
  0%{opacity:0;transform:translate(-50%,-50%) translate(0,0) rotate(0) scale(.1)}
  15%{opacity:1}
  100%{opacity:0;transform:translate(-50%,-50%) translate(var(--dx),var(--dy)) rotate(var(--rot)) scale(var(--sc))}
}

.fx-blot {
  position:absolute; width:var(--s); height:var(--s); transform:translate(-50%,-50%);
  background:radial-gradient(circle, color-mix(in srgb,var(--red) 80%,transparent) 0%,
                                     color-mix(in srgb,var(--red) 40%,transparent) 55%, transparent 72%);
  filter:blur(1px);
  animation:fxBlot 900ms cubic-bezier(.2,.75,.3,1) forwards;
}
@keyframes fxBlot {
  0%{opacity:.85;transform:translate(-50%,-50%) scale(.1)}
  100%{opacity:0;transform:translate(-50%,-50%) scale(1)}
}

.fx-flick {
  position:absolute; width:var(--s); height:calc(var(--s) * .28);
  transform:translate(-50%,-50%); background:var(--gold);
  -webkit-mask:var(--flick) center/100% 100% no-repeat;
          mask:var(--flick) center/100% 100% no-repeat;
  animation:fxFlick var(--d) cubic-bezier(.15,.75,.3,1) forwards;
}
@keyframes fxFlick {
  0%{opacity:0;transform:translate(-50%,-50%) translate(0,0) rotate(var(--rot0)) scale(.3)}
  14%{opacity:1}
  100%{opacity:0;transform:translate(-50%,-50%) translate(var(--dx),var(--dy)) rotate(var(--rot)) scale(var(--sc))}
}

@media (prefers-reduced-motion: reduce) {
  .fx-layer { display:none; }
}

/* Motion off. The toggle set this class but nothing acted on it, so
   "off" only suppressed click effects while every transition and
   scroll-reveal kept running. Now it means what it says. */
html.no-motion *,
html.no-motion *::before,
html.no-motion *::after {
  animation-duration:.001s !important;
  animation-iteration-count:1 !important;
  transition-duration:.001s !important;
  scroll-behavior:auto !important;
}
html.no-motion .fx-layer { display:none; }
/* reveals must not be left invisible when their transition is killed */
html.no-motion .rv { opacity:1 !important; transform:none !important; }
