/*
Theme Name: Past To Future
Theme URI: https://pasttofutureplugins.com
Author: Past To Future Plugins
Description: Shop and product theme for Past To Future Plugins. Machines photographed in a dark room: near-black plates with a lit top edge, Helvetica set tight, and one red used only for marks that signal.
Version: 0.5.0
Requires at least: 6.0
Requires PHP: 7.4
License: Proprietary
Text Domain: ptf
*/

/* Generated from ../mock-design.css. Edit that, not this. */
/* ============================================================================
   Past To Future — visual language

   The subject is machines photographed in a dark room. So: a ground that is not
   flat black but has light falling across it, plates that read as objects with
   a lit top edge rather than boxes with a border, and a single accent — the red
   off an instrument panel — used for every mark that signals rather than reads.

   Type does the rest. Titles are set in Helvetica Bold, tight, which is the face
   the hi-fi wordmarks of the period were drawn from. Instrument Sans stays out
   of the way in text, and every number is monospaced so prices and
   specifications line up down the page.
   ========================================================================= */

:root{
  /* A warm near-black, not a grey. Vintage gear is brown-black, not blue-black. */
  --ink-900:#09090A;
  --ink-850:#0C0C0E;
  --ink-800:#121215;
  --ink-700:#17171B;
  --edge:rgba(237,232,224,.07);       /* the lit top edge of a plate */
  --edge-hi:rgba(237,232,224,.14);
  --rule:rgba(237,232,224,.08);

  /* Grime on a plate. Three soft patches, none of them repeating, none of them
     above four and a half percent: an object that has sat in a rack picks up
     dirt in a few places, it does not get evenly coated. This is the only warm
     thing on the page and it is only ever on the units themselves. */
  --grime:
    radial-gradient(78% 60% at 6% 2%,   rgba(198,132,106,.048), transparent 62%),
    radial-gradient(56% 44% at 97% 92%, rgba(186,124,100,.038), transparent 66%),
    radial-gradient(42% 34% at 58% 16%, rgba(176,120,100,.020), transparent 72%);

  /* The face of a plate, and the face of one under the cursor. Both darker than
     they were: the object should sit into the room, not float off it. */
  --face:linear-gradient(176deg, var(--ink-800) 0%, var(--ink-850) 46%, var(--ink-900) 100%);
  --face-hi:linear-gradient(176deg, var(--ink-850) 0%, var(--ink-900) 58%, #070709 100%);

  --paper:#EDE8E0;                    /* warm off-white, not #FFF */
  --paper-2:#B8B2A8;
  --paper-3:#7C766D;

  /* The colour of a heading. The same as the body text in the dark theme, so
     nothing changes there; the light theme paints it flag blue while the body
     stays black. */
  --title:var(--paper);

  /* Secondary: the red off an old instrument panel. Slightly orange, slightly
     dusty — a modern signal red next to a warm black looks like a warning
     sticker, this looks like it was screen-printed in 1972. */
  /* Pushed up in saturation from #BE3A2B: still dusty enough to read as printed
     rather than as a warning, but it now carries against a near-black ground
     instead of sinking into it. */
  --red:#D4342A;
  --red-hot:#E8503F;
  --red-dim:rgba(212,52,42,.55);
  --fault:#E8503F;

  /* The room a section label and its rule take up: one line of 11px mono at the
     body's line height, plus the gap under it. A page that has no section label
     reserves the same space, so the first box on any page lands on the same
     line as the first card on a page that does. */
  --band-head-space:calc(11px * 1.65 + clamp(20px,2.4vw,30px));

  --plate:min(1240px,90vw);
  /* The shape of a cover. Measured off the artwork rather than assumed: the
     sleeves are 1005 by 1005, and every box that was drawn at 4:3 or 16:10 put
     grey bars down the sides of one and called it cropping. */
  --cover:1/1;
  --display:'Helvetica Neue','Arimo',Helvetica,Arial,sans-serif;
  --text:'Instrument Sans','Helvetica Neue',Arial,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,Menlo,monospace;

  --lift:0 1px 0 rgba(237,232,224,.06) inset, 0 24px 48px -32px rgba(0,0,0,.9);
  --lift-hi:0 1px 0 rgba(237,232,224,.11) inset, 0 34px 60px -30px rgba(0,0,0,1);
}

/* Native controls, scrollbars and the dropdown a select opens all follow the
   page rather than the operating system. */
:root{color-scheme:dark}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;color:var(--paper);
  font-family:var(--text);font-size:16px;line-height:1.65;letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;
  display:flex;flex-direction:column;min-height:100vh;
  /* Light falling from above, then the room. */
  background:
    radial-gradient(120% 60% at 50% -10%, rgba(212,52,42,.05), transparent 60%),
    linear-gradient(180deg, var(--ink-850) 0%, var(--ink-900) 60%);
  background-attachment:fixed;
}
main{flex:1 0 auto}
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
p{margin:0}
::selection{background:var(--red);color:var(--paper)}
:focus-visible{outline:2px solid var(--red-hot);outline-offset:3px}
.plate{width:var(--plate);margin-inline:auto}

/* ---- type -------------------------------------------------------------- */
h1,h2,h3{margin:0;font-family:var(--display);font-weight:700;letter-spacing:-.022em;line-height:1.05;color:var(--title)}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums lining-nums;letter-spacing:-.01em}

/* A section opens with a small label and a rule that runs to the edge. The rule
   is the thing that makes a page feel set rather than stacked. */
.band{padding:clamp(44px,5vw,76px) 0 0}
/* A band that follows a page heading has already been given its space by the
   heading. Without this the gap under a title is the heading's margin plus a
   whole band's padding on some pages and only the margin on others. */
.page + .band{padding-top:0}
.band-head{display:flex;align-items:baseline;gap:20px;margin-bottom:clamp(20px,2.4vw,30px)}
/* The section labels are the same red as the wordmark: they are the only two
   kinds of thing on the page that name what you are looking at. */
.band-head .label{
  font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:.2em;text-transform:uppercase;
  color:var(--red);white-space:nowrap;
}
.band-head .line{
  flex:1;height:9px;position:relative;
  background:linear-gradient(90deg,rgba(212,52,42,.30),var(--rule) 12%,transparent 88%);
  background-size:100% 1px;background-repeat:no-repeat;background-position:0 100%;
}
/* Ticks along the rule, sparse, like a printed scale. */
.band-head .line::before{
  content:"";position:absolute;inset:auto 0 0;height:5px;
  background:repeating-linear-gradient(90deg,var(--rule) 0 1px,transparent 1px 56px);
  -webkit-mask-image:linear-gradient(90deg,#000,transparent 78%);
          mask-image:linear-gradient(90deg,#000,transparent 78%);
}

/* ---- masthead ---------------------------------------------------------- */
.site-head{position:sticky;top:0;z-index:60;background:rgba(9,9,10,.72);backdrop-filter:blur(16px) saturate(1.4)}
.site-head::after{content:"";position:absolute;inset:auto 0 0;height:1px;background:var(--rule)}
.site-head .plate{display:flex;align-items:center;gap:18px;height:68px}
/* The wordmark. 20px rather than 17: it is the only thing in the bar that is
   not navigation, so it should not be the same size as navigation. */
.brand{
  font-family:var(--display);font-weight:700;font-size:20px;letter-spacing:-.022em;
  white-space:nowrap;
}
.brand em{font-style:normal;color:var(--red)}

.nav{display:flex;align-items:center;gap:28px;margin-left:auto;min-width:0}
.nav a{font-size:14.5px;color:var(--paper-2);white-space:nowrap;transition:color .18s ease}
.nav a:hover{color:var(--paper)}
/* The section you are in, said quietly. */
.nav a.on{color:var(--paper)}
.nav .cart{font-family:var(--mono);font-size:13px;letter-spacing:.02em}

/* ---- the object -------------------------------------------------------- */
/* Not a card: a plate with a lit top edge and a shadow under it. No hard
   border on four sides, which is what made the old one read as a box. */
.obj{
  position:relative;display:flex;flex-direction:column;overflow:hidden;
  border-radius:10px;
  /* The plate, with its dirt on it. */
  background-image:var(--grime), var(--face);
  /* Top, left and right only — the bottom of a plate is in shadow, and a line
     all the way round is what turns an object back into a box. Inset shadows
     rather than a bordered pseudo-element, so ::before is free for the sheen. */
  box-shadow:var(--lift),
             inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
  transition:transform .32s cubic-bezier(.2,.7,.2,1), box-shadow .32s ease, background .32s ease;
}
.obj:hover{
  transform:translateY(-3px);
  background-image:var(--grime), var(--face-hi);
  box-shadow:var(--lift-hi),
             inset 0 1px 0 var(--edge-hi), inset 1px 0 0 var(--edge-hi), inset -1px 0 0 var(--edge-hi);
}

/* ---- the analog layer ---------------------------------------------------
   Three things, all of them quiet. A panel has grain; metal catches light when
   you move past it; and a unit that is powered has a lamp on it. Anything
   louder than this becomes a novelty by next year. */

/* 1. Grain, and the brush under it.
      At rest the plate is almost plain: grain at 3.5%, felt rather than seen.
      Under the cursor a fine brushed grain comes up, the way anodised metal
      shows its direction when light moves across it. Two layers rather than one
      because grain alone reads as noise, and brush alone reads as a pattern. */
.obj::after{
  content:"";position:absolute;inset:0;pointer-events:none;border-radius:10px;
  opacity:.035;
  background-image:
    repeating-linear-gradient(96deg,
      rgba(237,232,224,.10) 0 1px,
      transparent 1px 2px,
      rgba(0,0,0,.10) 2px 3px,
      transparent 3px 5px),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix type='saturate' values='0'/></filter><rect width='140' height='140' filter='url(%23n)'/></svg>");
  background-size:auto, 140px 140px;
  mix-blend-mode:overlay;
  transition:opacity .45s ease;
}
/* Barely more than double, which on a near-black face is the difference between
   a flat fill and a machined one. Past this it starts to look like a texture
   someone applied. */
.obj:hover::after{opacity:.085}

/* 2. The sheen. A soft band of light that crosses the unit on hover, the way it
      does when you lean past a rack. It runs the full height of the plate now,
      faceplate and text together, because light does not stop at the picture.
      z-index puts it over the body copy; at five percent it does not cost the
      type any legibility. */
.obj::before{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:2;border-radius:10px;
  background:linear-gradient(105deg,transparent 38%,rgba(237,232,224,.05) 48%,rgba(237,232,224,.01) 56%,transparent 66%);
  transform:translateX(-120%);
  transition:transform .9s cubic-bezier(.22,.68,.3,1);
}
.obj:hover::before{transform:translateX(120%)}

/* 3. The lamp. Dark when idle, lit when the unit is under the cursor. */
.obj .body{position:relative}
.obj .body::before{
  content:"";position:absolute;top:26px;right:22px;width:6px;height:6px;border-radius:50%;
  background:#2A1917;box-shadow:0 0 0 1px rgba(0,0,0,.6) inset;
  transition:background .3s ease, box-shadow .3s ease;
}
/* The one thing on the page that behaves like hardware: dark until the unit is
   under the cursor, then lit. Red, because a power lamp is red. */
.obj:hover .body::before{
  background:var(--red-hot);
  box-shadow:0 0 0 1px rgba(0,0,0,.5) inset,
             0 0 12px 2px rgba(216,80,63,.65),
             0 0 26px 6px rgba(212,52,42,.30);
}

.obj .shot .ph::before{
  content:"";position:absolute;inset:0;border-radius:5px;pointer-events:none;
  border:1px solid var(--edge);
  box-shadow:0 1px 0 rgba(237,232,224,.09) inset;
}

.obj .shot{position:relative;aspect-ratio:var(--cover);display:grid;place-items:center;overflow:hidden}
/* The pool of light the machine sits in. */
.obj .shot::before{
  content:"";position:absolute;inset:0;
  background:radial-gradient(58% 52% at 50% 38%, rgba(237,232,224,.085), transparent 68%);
}
/* Contained, not cropped. These sleeves carry their own titles across the top
   and filling the box cut straight through one. */
.obj .shot img{width:100%;height:100%;object-fit:contain;position:relative;padding:8px}
/* The faceplate itself: brushed horizontally, with a machined edge. Darker than
   it was, because everything the cursor lands on went darker with it. */
.obj .shot .ph{
  position:relative;width:74%;aspect-ratio:16/9;border-radius:5px;
  background:
    repeating-linear-gradient(0deg, rgba(237,232,224,.03) 0 1px, transparent 1px 3px),
    linear-gradient(168deg,#191920,#0F0F13 62%);
  box-shadow:0 1px 0 rgba(237,232,224,.10) inset, 0 22px 34px -22px rgba(0,0,0,1);
}
.obj .shot .ph::after{
  content:"";position:absolute;left:10%;right:10%;top:47%;height:1px;
  background:repeating-linear-gradient(90deg,rgba(237,232,224,.13) 0 1px,transparent 1px 24px);
}
.obj .tag{
  position:absolute;top:14px;left:14px;z-index:2;
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:#F6EDE6;background:var(--red);padding:4px 9px;border-radius:3px;line-height:1;
  box-shadow:0 6px 18px -8px rgba(212,52,42,.75);
}

.obj .body{padding:20px 22px 22px;display:flex;flex-direction:column;gap:9px;flex:1}
.obj h3{font-size:21px}
.obj .said{color:var(--paper-2);font-size:14.5px;line-height:1.6;flex:1}
.obj .spec{font-family:var(--mono);font-size:11px;letter-spacing:.06em;color:var(--paper-3)}
.obj .foot{
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  margin-top:6px;padding-top:15px;border-top:1px solid var(--rule);
}
.obj .price{font-family:var(--mono);font-size:14px;font-variant-numeric:tabular-nums;color:var(--paper)}
.obj .try{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--red);
  display:inline-flex;align-items:center;gap:7px;
}
/* A tick of the kind engraved next to a switch position. */
.obj .try::before{content:"";width:14px;height:1px;background:currentColor;opacity:.55}

/* The whole card is one click target. The cover link lies over the card and
   takes the click wherever it lands -- picture, name, blurb or bare space --
   while Try and Add to cart lift themselves above it and keep their own. The
   sheen sits above too but lets clicks through, so nothing here fights it. */
.obj .card-cover{position:absolute;inset:0;z-index:1}
.obj .card-cover:focus-visible{outline:2px solid var(--red);outline-offset:-3px}
/* Both buttons lift above the cover link so they keep their own clicks. */
.obj .foot .ctas{position:relative;z-index:3}

/* On the small three-across grid cards the two buttons are equal-width blocks
   stacked on the right of the foot, clear of the price, rather than unequal ones
   crowding the digits. The wide newest-release card is left as it was, the two
   side by side, which reads best across that much width. */
.obj:not(.hero-obj) .foot{align-items:center}
.obj:not(.hero-obj) .foot .ctas{
  flex-direction:column;align-items:stretch;flex-wrap:nowrap;
  gap:8px;flex:0 0 auto;margin-left:auto;
}
.obj:not(.hero-obj) .foot .ctas .btn{width:100%;justify-content:center;white-space:nowrap}

/* ---- the newest release, given the room it deserves -------------------- */
/* The newest release, given the room it deserves and not a pixel more.
   The sleeve is square, so the wide column it used to sit in made it as tall as
   it was broad: on a large screen that was most of the window for one picture.
   A narrower column, and a ceiling for when the two stack on a phone. */
.hero-obj{display:grid;grid-template-columns:minmax(0,.72fr) minmax(0,1.28fr);align-items:stretch}
@media (max-width:900px){.hero-obj{grid-template-columns:1fr}}
.hero-obj .shot{
  aspect-ratio:var(--cover);border-right:1px solid var(--rule);
  max-height:min(46vh,440px);
}
@media (max-width:900px){
  .hero-obj .shot{
    border-right:0;border-bottom:1px solid var(--rule);
    max-height:none;max-width:380px;margin:0 auto;width:100%;
  }
}
.hero-obj .body{justify-content:center;padding:clamp(26px,3vw,40px);gap:14px}
.hero-obj h3{font-size:clamp(28px,3.4vw,42px);letter-spacing:-.026em}
.hero-obj .said{font-size:16px;max-width:46ch;flex:0}
.hero-obj .foot{margin-top:12px}
.hero-obj .price{font-size:17px}

.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,1.6vw,22px)}
@media (max-width:1000px){.grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:640px){.grid{grid-template-columns:1fr}}

/* One height, everywhere.
   Without a line-height of its own a button took the line-height of whatever
   was around it: 41 pixels in a flex row, 47 in a paragraph, so the same
   button was two different sizes on two pages. */
.btn{
  display:inline-flex;align-items:center;gap:8px;font-family:var(--text);font-size:14px;font-weight:500;
  line-height:1.2;padding:11px 20px;border-radius:7px;cursor:pointer;transition:.2s ease;
  background:linear-gradient(180deg,var(--red-hot),var(--red));color:#FFF;
  border:1px solid transparent;box-shadow:0 10px 24px -14px rgba(212,52,42,.85);
}
.btn:hover{filter:brightness(1.06);transform:translateY(-1px)}
.btn.ghost{background:none;color:var(--paper);box-shadow:none;border:1px solid var(--edge-hi)}
.btn.ghost:hover{border-color:var(--paper-3);transform:none;filter:none}

/* ---- footer ------------------------------------------------------------ */
.site-foot{margin-top:clamp(64px,8vw,110px);padding:clamp(40px,5vw,60px) 0 48px;border-top:1px solid var(--rule);flex:0 0 auto}
.site-foot .plate{display:grid;grid-template-columns:1.4fr repeat(3,1fr);gap:34px;align-items:baseline}
@media (max-width:900px){.site-foot .plate{grid-template-columns:repeat(3,1fr)} .site-foot .word{grid-column:1/-1}}
@media (max-width:620px){.site-foot .plate{grid-template-columns:1fr 1fr}}
.site-foot .word{font-family:var(--display);font-weight:700;font-size:20px;letter-spacing:-.022em;margin:0}
.site-foot .word em{font-style:normal;color:var(--red)}
.site-foot h4{font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;color:var(--paper-3);margin:0 0 14px;font-weight:400}
.site-foot ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.site-foot a{color:var(--paper-2);font-size:14.5px;transition:color .18s ease}
.site-foot a:hover{color:var(--red-hot)}
.site-foot .fine{grid-column:1/-1;margin-top:30px;padding-top:24px;border-top:1px solid var(--rule);color:var(--paper-3);font-size:13.5px;max-width:74ch}
/* The trading name and the registration numbers, which a Dutch shop has to
   show somewhere a customer can find without hunting for it. */
.site-foot .fine .who{display:block;margin-top:8px;font-size:12.5px;color:var(--paper-3);opacity:.8}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* ==========================================================================
   Screens beyond the front page.
   Everything below reuses the plate: a near-black face with a lit top edge,
   mono capitals for anything that labels rather than reads, and the red kept
   for marks that signal. Nothing here introduces a new colour or a new shape.
   ========================================================================== */

/* A page that is not the front page starts below the masthead, not against it. */
.page{padding:clamp(30px,4vw,52px) 0 0}
.crumb{
  font-family:var(--mono);font-size:11px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper-3);margin-bottom:18px;display:flex;gap:10px;align-items:center;
}
.crumb a{color:var(--paper-3)}
.crumb a:hover{color:var(--red-hot)}
.crumb .sep{opacity:.5}

/* Every page hangs its content off the same line. The title occupies one line
   and the sentence under it is given two lines of room whether it uses them,
   uses one, or is not there at all. Change page and nothing below shifts. */
.head{margin-bottom:clamp(22px,3vw,34px)}
.head h1{font-size:clamp(30px,4.4vw,52px);line-height:1.02;margin-bottom:12px;min-height:1.02em}
.head .said{
  font-size:16.5px;line-height:1.65;color:var(--paper-2);max-width:62ch;
  min-height:calc(1.65 * 16.5px);
}
/* A page with no sentence still reserves the room it would have taken.

   One line, not two. Two was the sentence's worst case rather than its usual
   one, so on every page whose sentence fits on a single line it left a blank
   line hanging under the title, and on a phone that reads as the page having
   forgotten to load. Reserving one line keeps the pages lined up in the case
   that actually happens, and the page whose sentence wraps now pushes its
   content down by one line instead of every other page carrying a hole so that
   it does not have to. */
.head:not(:has(.said))::after{content:"";display:block;height:calc(1.65 * 16.5px)}
/* And a page that runs straight into its boxes, with no section label between,
   reserves the label's space too. Support and Account now line their panels up
   with the cards on Plugins instead of sitting a label's height higher. */
/* A page with boxes on it reserves the space a band's label would have taken,
   so the first box lines up with the first box on every other page.
   A page that is only prose has nothing to line up with, and reserving it there
   left a hole the height of a paragraph between the title and the first line.
   Support, Terms, Privacy, Refunds and Activate are all prose. */
.page:not(:has(+ .band)):not(:has(.prose)) .head{
  margin-bottom:calc(clamp(22px,3vw,34px) + var(--band-head-space));
}

/* A page with no breadcrumb reserves its line too, so that landing on the 404
   does not move the title 36 pixels up the screen from where it sits on every
   other page. One line of 11px mono at the body's line height, plus its gap. */
.page .plate > .head:first-child{margin-top:calc(11px * 1.65 + 18px)}

/* The plate again, without the hover behaviour: panels are read, not chosen. */
.panel{
  position:relative;border-radius:10px;overflow:hidden;
  background:var(--face);
  box-shadow:var(--lift),
             inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
  padding:clamp(20px,2.4vw,30px);
}
/* Stacked panels are spaced. Panels sitting beside each other in a grid are
   NOT stacked, and this rule was pushing every right hand box down by 18px. */
.panel + .panel{margin-top:18px}
.cols > .panel + .panel{margin-top:0}
.panel h2{font-size:20px;letter-spacing:-.019em;margin-bottom:6px}
.panel h3{font-size:16px;letter-spacing:-.015em;margin-bottom:6px}
.panel .said{color:var(--paper-2);font-size:15px;max-width:64ch}
.panel .said + .said{margin-top:12px}

/* Small mono capitals. The same thing the section labels do, one level down. */
.lab{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-3);display:block;margin-bottom:10px;
}
.lab.red{color:var(--red)}

.cols{display:grid;gap:18px}
.cols.two{grid-template-columns:1fr 1fr}
.cols.three{grid-template-columns:repeat(3,1fr)}
.cols.side{grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);align-items:start}
@media (max-width:900px){.cols.two,.cols.three,.cols.side{grid-template-columns:1fr}}

/* ---- product ------------------------------------------------------------ */
.shot-big{
  aspect-ratio:16/9;border-radius:10px;overflow:hidden;position:relative;
  background:
    repeating-linear-gradient(0deg, rgba(237,232,224,.03) 0 1px, transparent 1px 3px),
    linear-gradient(168deg,#191920,#0F0F13 62%);
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
/* The demo well. There is no video in it yet, and it says so rather than
   pretending: a still frame with nothing behind it is worse than an empty one. */
.video{
  aspect-ratio:16/9;border-radius:10px;position:relative;display:grid;place-items:center;
  background:linear-gradient(176deg,var(--ink-800),var(--ink-900));
  box-shadow:inset 0 0 0 1px var(--edge);
  color:var(--paper-3);text-align:center;
}
.video .play{
  width:54px;height:54px;border-radius:50%;display:grid;place-items:center;margin:0 auto 12px;
  box-shadow:inset 0 0 0 1px var(--edge-hi);
}
.video .play::before{
  content:"";width:0;height:0;margin-left:4px;
  border-left:13px solid var(--red);border-top:8px solid transparent;border-bottom:8px solid transparent;
}
.video .cap{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase}

.buy .price{font-family:var(--mono);font-size:30px;font-variant-numeric:tabular-nums;color:var(--paper);letter-spacing:-.02em}
.buy .under{font-size:13.5px;color:var(--paper-3);margin-top:4px}
.buy .actions{display:flex;flex-wrap:wrap;gap:10px;margin:20px 0 4px}

/* Specifications read as a printed table, not as prose. */
.spec-table{width:100%;border-collapse:collapse;font-size:14.5px}
.spec-table th,.spec-table td{text-align:left;padding:11px 0;border-top:1px solid var(--rule);vertical-align:top}
.spec-table tr:first-child th,.spec-table tr:first-child td{border-top:0}
.spec-table th{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper-3);font-weight:400;width:42%;padding-right:16px;
}
.spec-table td{color:var(--paper-2)}

/* ---- forms --------------------------------------------------------------- */
.form{display:grid;gap:14px;max-width:none}
/* FIX: rows at their natural height, pinned to the top.
   A .field is a grid, and two of them side by side in .row2 are stretched to the
   height of the taller one. Without this the shorter field's rows grew to fill
   that height: the select box on the left came out nearly twice as tall as the
   text box on the right, and sat sixty pixels lower than it. */
.field{display:grid;gap:7px;align-content:start}
.field > label{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-3);
}
.field input,.field select,.field textarea{
  width:100%;font-family:var(--text);font-size:15px;color:var(--paper);
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:7px;
  padding:11px 13px;transition:border-color .18s ease, box-shadow .18s ease;
}
/* The one control the browser insists on drawing itself. Strip it back to a
   field and put our own mark on the right: a single chevron, in the red, the
   way a selector is engraved on a panel rather than moulded in plastic. */
.field select{
  -webkit-appearance:none;appearance:none;cursor:pointer;
  padding-right:38px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'><path d='M1 1.2 5.5 5.7 10 1.2' fill='none' stroke='%23D4342A' stroke-width='1.6' stroke-linecap='square'/></svg>");
  background-repeat:no-repeat;
  background-position:right 14px center;
  background-size:11px 7px;
}
.field select:hover{border-color:var(--red-dim)}
.field select::-ms-expand{display:none}
.field textarea{min-height:120px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:0;border-color:var(--red-dim);box-shadow:0 0 0 3px rgba(212,52,42,.13);
}
.field .hint{font-size:12.5px;color:var(--paper-3)}
/* A tick and a sentence. Not a .field: a checkbox is not a column with a mono
   capital over it, and the label has to be clickable across its whole width. */
.agree{display:grid;grid-template-columns:auto 1fr;gap:11px;align-items:start;cursor:pointer}
.agree input{width:16px;height:16px;margin:2px 0 0;accent-color:var(--red);flex:none}
.agree span{font-size:14.5px;color:var(--paper-2);line-height:1.5}
.agree a{color:var(--red)}
/* The field only a robot fills in. Off screen rather than display:none, which
   some of them check for. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media (max-width:620px){.row2{grid-template-columns:1fr}}
/* A row of things you can do, on one line, on the same baseline. Wherever it
   appears: inside a form, under a table, at the foot of a panel. */
.actions{display:flex;flex-wrap:wrap;align-items:center;gap:12px}
.form .actions{gap:14px;margin-top:6px}
.alt{font-size:14px;color:var(--paper-3)}
.alt a{color:var(--red);text-decoration:none}
.alt a:hover{color:var(--red-hot)}

/* ---- tables -------------------------------------------------------------- */
.tbl{width:100%;border-collapse:collapse;font-size:14.5px}
.tbl th{
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper-3);font-weight:400;text-align:left;padding:0 14px 11px 0;border-bottom:1px solid var(--rule);
}
.tbl td{padding:14px 14px 14px 0;border-bottom:1px solid var(--rule);color:var(--paper-2);vertical-align:middle}
.tbl tr:last-child td{border-bottom:0}
.tbl .num{color:var(--paper);font-family:var(--mono);font-variant-numeric:tabular-nums}
.tbl .right{text-align:right;padding-right:0}
/* FIX: a right-aligned column drops its right padding so the number sits on the
   column edge, which is correct when it is the last column and wrong the moment
   another one follows: the money and the state ran into each other, and the two
   headings printed as one word. The padding comes back on whatever comes next. */
.tbl .right + th,
.tbl .right + td{padding-left:18px}
.tbl .name{color:var(--paper);font-weight:500}
.scroll-x{overflow-x:auto;scrollbar-width:thin}
/* FIX: a table dropped straight under a paragraph had its heading row touching
   the last line of prose, so the column names read as part of the sentence. */
.panel .said + .scroll-x,
.panel .said + .tbl,
.panel .said + .kv,
.panel .said + .stats,
.panel .said + .grid{margin-top:18px}
.panel .lab + .scroll-x,
.panel .lab + .tbl,
.panel .lab + .kv{margin-top:14px}

/* A flag is a wide glyph and the name ran straight into it. */
.flag{margin-right:9px;font-size:15px;line-height:1}
/* An email address, a licence key and a machine name are all one long word with
   nothing to break at, so in a table cell they ran past the edge of the plate
   and were clipped. Nothing on this site is allowed to be cut off mid-word. */
.tbl td,.tbl th{overflow-wrap:anywhere}

/* A field and its value, stacked. Used where the value is long enough that a
   two-column row would clip it: the account panel, the licence detail. */
.kv{margin:0;display:block}
.kv > div{padding:14px 0;border-bottom:1px solid var(--rule)}
.kv > div:first-child{padding-top:4px}
.kv > div:last-child{border-bottom:0;padding-bottom:0}
.kv dt{
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper-3);margin:0 0 6px;
}
.kv dd{
  margin:0;color:var(--paper);font-size:16px;line-height:1.45;overflow-wrap:anywhere;
}
.kv dd .unset{color:var(--paper-3)}

/* A state, said once and quietly. */
.pill{
  display:inline-block;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  padding:4px 8px;border-radius:3px;color:var(--paper-2);box-shadow:inset 0 0 0 1px var(--edge-hi);
}
.pill.on{color:#F6EDE6;background:var(--red);box-shadow:none}
.pill.warn{color:var(--red-hot);box-shadow:inset 0 0 0 1px var(--red-dim)}

/* ---- numbers ------------------------------------------------------------- */
/* However many there are, evenly.
   Fixed at four columns, a fifth tile dropped onto a row of its own and sat
   there a quarter of the width of the page looking like a mistake. */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px}
@media (max-width:900px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat{
  border-radius:10px;padding:18px 18px 16px;
  background:var(--face);
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
.stat .v{font-family:var(--mono);font-size:26px;font-variant-numeric:tabular-nums;letter-spacing:-.02em;color:var(--paper)}
.stat .k{
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper-3);margin-top:6px;
}

/* ---- tabs ---------------------------------------------------------------- */
.tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:18px;border-bottom:1px solid var(--rule);padding-bottom:0}
.tabs a{
  font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);padding:10px 14px;border-radius:7px 7px 0 0;position:relative;transition:color .18s ease;
}
.tabs a:hover{color:var(--paper-2)}
.tabs a.on{color:var(--red)}
.tabs a.on::after{content:"";position:absolute;inset:auto 10px -1px;height:1px;background:var(--red)}

/* ---- prose --------------------------------------------------------------- */
.prose{max-width:74ch}
/* The measure is for reading, not for buying.
   Cart, checkout and the account screens are ordinary WordPress pages, so
   page.php renders them and wraps their content in article.prose, the same
   wrapper Support and Terms get. The 74ch measure that keeps a paragraph
   readable then caps the whole shop. On a 1440 wide window the plate is 1240
   pixels and the checkout was being drawn in 789 of them, leaving 451 pixels of
   nothing down the right hand side and squeezing the order and payment column
   to 242. That is the checkout looking squeezed and dragged down. All three of
   these pages lay themselves out in their own grids further down this sheet and
   set their own widths, so the measure is released for them and for nothing
   else. */
.woocommerce-cart .prose,
.woocommerce-checkout .prose,
.woocommerce-account .prose{max-width:none}
.prose h2{font-size:20px;margin:30px 0 8px}
.prose h2:first-child{margin-top:0}
.prose p{color:var(--paper-2);font-size:15.5px;margin:0 0 12px}
/* The dev log is reference text: It is looked something up in rather than read
   through, so it is set smaller than the prose around it. The measure stays in
   ch, so the column narrows with the type and a line holds the same number of
   characters it did before. */
.devlog h2{font-size:15px;margin:22px 0 5px}
.devlog p{font-size:13px;line-height:1.62;margin:0 0 10px}
/* Belt to the filter's braces: an empty paragraph the editor left behind takes
   no room, whatever shape it arrives in. */
.prose p:empty,
.prose p:has(> br:only-child){display:none}
.prose ul{color:var(--paper-2);font-size:15.5px;margin:0 0 12px;padding-left:20px}
.prose li{margin:0 0 7px}
.prose strong{color:var(--paper);font-weight:600}

/* ---- cart ---------------------------------------------------------------- */
.line-item{display:grid;grid-template-columns:96px 1fr auto;gap:16px;align-items:center;padding:16px 0;border-bottom:1px solid var(--rule)}
.line-item:last-of-type{border-bottom:0}
.line-item .mini{
  aspect-ratio:16/10;border-radius:6px;
  background:repeating-linear-gradient(0deg, rgba(237,232,224,.03) 0 1px, transparent 1px 3px),
             linear-gradient(168deg,#191920,#0F0F13 62%);
  box-shadow:inset 0 0 0 1px var(--edge);
}
.line-item h3{font-size:16px;margin-bottom:3px}
.line-item .said{font-size:13px;color:var(--paper-3)}
.line-item .price{font-family:var(--mono);font-size:16px;color:var(--paper);font-variant-numeric:tabular-nums}

/* On a phone the price comes off the end of the row and goes under the name.
   Three columns inside a panel inside a 375 wide screen left the middle one
   ninety two pixels wide, so the plugin's name broke over two lines and the
   line under it broke over three. Two columns give that middle one two hundred
   and twelve instead, which is a line of text rather than a column of words. */
@media (max-width:620px){
  .line-item{grid-template-columns:72px minmax(0,1fr);gap:8px 14px;align-items:start}
  .line-item .price{grid-column:2;justify-self:start}
}
.totals{margin-top:6px;border-top:1px solid var(--rule);padding-top:16px;display:grid;gap:9px}
.totals div{display:flex;justify-content:space-between;font-size:14.5px;color:var(--paper-2)}
.totals .grand{font-size:18px;color:var(--paper);padding-top:9px;border-top:1px solid var(--rule)}
.totals .num{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ---- notices ------------------------------------------------------------- */
.note{
  border-radius:8px;padding:14px 16px;font-size:14.5px;color:var(--paper-2);
  box-shadow:inset 0 0 0 1px var(--edge-hi);background:rgba(237,232,224,.02);
}
.note.red{box-shadow:inset 0 0 0 1px var(--red-dim)}
.note strong{color:var(--paper)}
.empty{padding:34px 0;text-align:center;color:var(--paper-3);font-size:15px}

/* Woo's own notices.
   These are the boxes it prints for "no products found", "no downloads yet",
   "please log in", a coupon result, a validation failure. Its stylesheet drew
   them as a white slab with a blue rule across the top and a blue tick, which
   on a black page is the brightest thing on the screen. Woo's sheets are not
   loaded at all now (see functions.php), so this is the whole of their design
   rather than an override of it.

   All three read as the same plate. Only the mark down the left changes: red
   for a failure, red for a message that needs acting on, grey for information. */
.woocommerce-notices-wrapper:empty{display:none}
.woocommerce-notices-wrapper{display:block}
.woocommerce-message,
.woocommerce-info,
.woocommerce-error,
.woocommerce-noreviews,
p.no-comments{
  display:flex;align-items:center;flex-wrap:wrap;gap:14px;
  margin:0 0 18px;padding:16px 18px;list-style:none;
  border:0;border-left:2px solid var(--edge-hi);border-radius:0 8px 8px 0;
  background:rgba(237,232,224,.028);
  color:var(--paper-2);font-family:var(--text);font-size:14.5px;line-height:1.55;
}
.woocommerce-message{border-left-color:var(--red)}
.woocommerce-error{border-left-color:var(--red);color:var(--paper)}
/* Woo prints errors as a <ul> of <li>. Flat, no bullets, no indent. */
.woocommerce-error li{margin:0;padding:0;list-style:none;width:100%}
.woocommerce-error li + li{margin-top:6px}
.woocommerce-message strong,
.woocommerce-info strong,
.woocommerce-error strong{color:var(--paper);font-weight:600}
.woocommerce-message a:not(.button),
.woocommerce-info a:not(.button),
.woocommerce-error a:not(.button){color:var(--red)}
/* The button Woo tucks inside a notice ("Browse products", "View cart") is
   pushed to the far end so the notice reads as one row rather than a sentence
   with something bolted onto it. */
.woocommerce-message .button,
.woocommerce-info .button,
.woocommerce-error .button{margin-left:auto;flex:none}
/* Its icon is a ::before with a webfont we do not ship, which came out as a
   blank square holding 3.5em of space. */
.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before{content:none;display:none}

/* Woo's own empty-cart page, for the case where the page is still the block or
   a plugin prints it: no giant crying face, no centring. */
.woocommerce .cart-empty,
.woocommerce .wc-empty-cart-message .cart-empty{
  text-align:left;font-size:16.5px;color:var(--paper-2);margin:0 0 18px;
}
.woocommerce .cart-empty::before,
.wc-block-cart__empty-cart__title,
.wc-block-cart__empty-cart__title + *{display:none}
.woocommerce .return-to-shop{margin:0}

/* Woo's password strength meter, hidden fields and the show/hide eye. */
.woocommerce form .form-row .password-input,
.woocommerce form .form-row .woocommerce-password-hint{width:100%}
.woocommerce form .form-row .password-input{position:relative;display:block}
.woocommerce .show-password-input{
  position:absolute;right:12px;top:12px;cursor:pointer;color:var(--paper-3);
}
.woocommerce .show-password-input::after{content:"\25CF\25CF\25CF";font-size:9px;letter-spacing:1px}
.woocommerce-password-strength{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  padding:8px 0 0;text-align:left;color:var(--paper-3);
}
.woocommerce-password-strength.short,
.woocommerce-password-strength.bad{color:var(--red)}
.woocommerce-password-strength.good,
.woocommerce-password-strength.strong{color:var(--paper-2)}
.woocommerce-password-hint{color:var(--paper-3);font-size:13px;display:block;margin-top:6px}

/* Woo's screen-reader text, which without its stylesheet prints on the page. */
.screen-reader-text,
.woocommerce form .form-row label.screen-reader-text{
  position:absolute !important;width:1px;height:1px;overflow:hidden;
  clip:rect(1px,1px,1px,1px);clip-path:inset(50%);white-space:nowrap;
}

/* Woo's two-up form rows, which its layout sheet floated. */
.woocommerce form .form-row-first,
.woocommerce form .form-row-last{width:100%;float:none}
.woocommerce form .form-row-wide{clear:none}
@media (min-width:721px){
  .woocommerce form .col2-set{display:grid;grid-template-columns:1fr 1fr;gap:0 clamp(16px,2vw,26px)}
  .woocommerce form .col2-set .col-1,
  .woocommerce form .col2-set .col-2{width:auto;float:none;min-width:0}
}

/* Woo's pagination, on the shop when there are more than nine plugins. */
.woocommerce nav.woocommerce-pagination{margin:clamp(24px,3vw,36px) 0 0;text-align:left}
.woocommerce nav.woocommerce-pagination ul{
  display:flex;gap:6px;border:0;margin:0;padding:0;list-style:none;
}
.woocommerce nav.woocommerce-pagination ul li{border:0;margin:0;overflow:visible}
.woocommerce nav.woocommerce-pagination ul li a,
.woocommerce nav.woocommerce-pagination ul li span{
  font-family:var(--mono);font-size:12px;padding:9px 13px;border-radius:7px;
  color:var(--paper-3);background:none;box-shadow:inset 0 0 0 1px var(--edge);
}
.woocommerce nav.woocommerce-pagination ul li span.current{color:var(--red);box-shadow:inset 0 0 0 1px var(--red-dim)}
.woocommerce nav.woocommerce-pagination ul li a:hover{color:var(--paper);background:none}

/* ==========================================================================
   The long product page.
   A plugin is a considered purchase, so the page is long and it argues. The
   structure is: what it is, then what it sounds like, then a section per thing
   it actually does, then the specification, then what happens after you buy.
   No new colours and no new shapes. The rhythm comes from alternating which
   side the image sits on and from a numbered index down the left, not from
   coloured blocks.
   ========================================================================== */

/* ---- hero ---------------------------------------------------------------- */
/* The words and the sleeve end level.
   The sleeve is square and was drawn at the full width of its column, which
   made it taller than everything beside it and left the two halves of the page
   agreeing about nothing. Now the words set the height of the row and the
   sleeve is a square of exactly that height, pushed to the outside edge. */
.phero{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(260px,.82fr);
  gap:clamp(28px,4vw,64px);align-items:stretch;
  padding:clamp(26px,4vw,54px) 0 clamp(30px,4vw,56px);
}
.phero > div:first-child{display:flex;flex-direction:column;justify-content:center;min-width:0}
@media (max-width:960px){.phero{grid-template-columns:1fr}}

/* Name, what kind of thing it is, and the badge. One line, the way a unit has
   a plate on its front. */
.pmark{display:flex;align-items:center;gap:14px;margin-bottom:clamp(20px,2.6vw,30px)}
.pmark .ico{
  width:52px;height:52px;border-radius:11px;flex:0 0 auto;
  background:
    repeating-linear-gradient(0deg, rgba(237,232,224,.05) 0 1px, transparent 1px 3px),
    linear-gradient(168deg,#1D1D24,#0F0F13 70%);
  box-shadow:inset 0 1px 0 var(--edge-hi), inset 0 0 0 1px var(--edge);
  position:relative;
}
/* A lamp, unlit, because the unit on the page is not running. */
.pmark .ico::after{
  content:"";position:absolute;right:9px;bottom:9px;width:5px;height:5px;border-radius:50%;
  background:var(--red);box-shadow:0 0 8px 1px rgba(212,52,42,.5);
}
/* With artwork on it, the plate is the artwork: no engraved texture behind it
   and no lamp on top of it, both of which read as damage over a picture. */
.pmark .ico.has-art,
.prodbar .ico.has-art{background:var(--ink-900);overflow:hidden;box-shadow:inset 0 0 0 1px var(--edge-hi)}
.pmark .ico.has-art::after,
.prodbar .ico.has-art::after{content:none}
.pmark .ico.has-art img,
.prodbar .ico.has-art img{
  width:100%;height:100%;display:block;object-fit:contain;aspect-ratio:var(--cover);
}
.pmark .who{display:flex;flex-direction:column;gap:2px;min-width:0}
.pmark .nm{font-family:var(--display);font-weight:700;font-size:21px;letter-spacing:-.022em}
.pmark .kind{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-3);
}
.pmark .badge{
  margin-left:auto;font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:#F6EDE6;background:var(--red);padding:5px 10px;border-radius:3px;white-space:nowrap;
}

.phero h1{font-size:clamp(34px,5vw,60px);line-height:1;letter-spacing:-.028em;margin-bottom:clamp(18px,2.2vw,26px)}

/* The claims. A short list, each one a thing the plugin does rather than a
   thing we feel about it. */
.points{list-style:none;margin:0 0 clamp(24px,3vw,34px);padding:0;display:grid;gap:11px}
.points li{position:relative;padding-left:24px;font-size:16px;color:var(--paper-2);line-height:1.5}
.points li::before{
  content:"";position:absolute;left:0;top:.73em;width:11px;height:1px;background:var(--red);
}
.points li strong{color:var(--paper);font-weight:500}
.points li a{color:var(--red);text-decoration:underline;text-underline-offset:3px}
.points li a:hover{color:var(--red-hot)}

/* ---- what it runs on -----------------------------------------------------
   The last thing between reading about a plugin and buying it, so it is given
   the weight of a plate rather than of a footnote. One row of facts, each with
   the same short rule in front of it that the claims above use, so the two
   lists read as the same voice: the claims are what it does, this is what it
   needs. The platform with no build is in the red, because the whole point of
   the block is that somebody scanning it stops on that one.

   Every value is one unbreakable phrase. They wrap onto a second and a third
   line on a phone, which is the design: a row of facts that stays one line by
   shrinking is a row nobody reads. */
.runs{
  display:flex;flex-wrap:wrap;align-items:center;gap:11px 16px;
  margin:0;padding:14px 16px;border-radius:8px;
  background:rgba(237,232,224,.02);box-shadow:inset 0 0 0 1px var(--edge-hi);
}
/* The base .lab carries a 10px bottom margin for when it sits above a block.
   Here it sits inline in a centred row, so that margin would shove "Runs on"
   up off the line the platforms sit on. Clear it. */
.runs .lab{flex:0 0 auto;margin:0}
.runs .v{
  display:inline-flex;align-items:center;gap:9px;
  font-size:14.5px;line-height:1.4;color:var(--paper-2);
}
/* The rule in front of each fact is also what separates one from the next, so
   the row needs no dots or pipes between its parts. */
.runs .v::before{content:"";flex:0 0 auto;width:11px;height:1px;background:var(--paper-3)}
.runs .v.off{color:var(--red-hot)}
.runs .v.off::before{background:var(--red)}

/* The hero's claims already leave a gap above this, and the trial button, when
   there is one, follows it. Nothing here adds a margin of its own, so a hero
   with no button under it ends on the block rather than on empty space. */
.points + .runs{margin-top:0}
.runs + .ctas{margin-top:clamp(22px,2.8vw,30px)}
.buy .said + .runs{margin-top:16px}

/* The line for a visitor on a machine none of this runs on.
   It is in the markup for everybody and revealed by a class the browser puts
   on the document, never by the User-Agent this server was sent: the page
   cache in front of the site would otherwise serve one visitor's guess to
   every visitor after them. Nothing is hidden or disabled by it, because
   buying a Mac plugin from a Windows desktop for the Mac in the next room is
   an ordinary thing to do. */
.win-note{display:none;margin-top:14px}
.on-windows .win-note{display:block}
/* Air underneath only when something follows it. In the cart the order sits
   under this note and four pixels of gap read as the two being one thing; in
   the hero and on the checkout it is the last thing in its column and a margin
   there would be the empty space at the bottom of a box. */
.win-note:not(:last-child){margin-bottom:16px}

/* The same fact, three words of it, in the bar that follows the reader down
   the page. The bar holds the only Add to cart on a product page, so the
   platform must never be further away than the button it qualifies. */
.runs-tag{
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-2);box-shadow:inset 0 0 0 1px var(--edge-hi);
  padding:4px 8px;border-radius:3px;white-space:nowrap;flex:0 0 auto;
}

.ctas{display:flex;flex-wrap:wrap;gap:12px;align-items:stretch}
.ctas .btn{padding:14px 22px;font-size:15px;border-radius:8px}
.ctas .btn .was{opacity:.62;text-decoration:line-through;margin-left:4px;font-variant-numeric:tabular-nums}
.ctas .sub{display:flex;flex-direction:column;gap:2px;align-items:flex-start;justify-content:center}
.ctas .sub small{font-size:11.5px;color:var(--paper-3);font-family:var(--mono);letter-spacing:.08em}

/* ---- the sticky bar ------------------------------------------------------
   It is placed after the hero rather than fixed over it, so it arrives when
   the hero has gone and never covers the thing you are reading. No script. */
.prodbar{
  position:sticky;top:68px;z-index:50;
  background:rgba(9,9,10,.82);backdrop-filter:blur(16px) saturate(1.4);
  border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);
}
.prodbar .plate{display:flex;align-items:center;gap:14px;height:60px}
.prodbar .ico{width:30px;height:30px;border-radius:7px}
.prodbar .ico::after{right:5px;bottom:5px;width:4px;height:4px}
.prodbar .nm{font-size:16px}
.prodbar .jump{display:flex;gap:22px;margin-left:auto;min-width:0;overflow-x:auto;scrollbar-width:none}
.prodbar .jump::-webkit-scrollbar{display:none}
.prodbar .jump a{
  font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);white-space:nowrap;transition:color .18s ease;
}
.prodbar .jump a:hover{color:var(--paper)}
.prodbar .btn{padding:9px 16px;font-size:13.5px;margin-left:22px;flex:0 0 auto}
@media (max-width:760px){.prodbar .jump{display:none}}

/* ---- alternating feature rows -------------------------------------------- */
.feature-row{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(26px,4vw,62px);align-items:center;
  padding:clamp(38px,5.5vw,80px) 0;border-top:1px solid var(--rule);
}
@media (max-width:900px){.feature-row{grid-template-columns:1fr;gap:26px}}
/* Odd rows put the picture on the right. Even rows swap it, which is the only
   thing giving the page its beat. */
.feature-row.wide{grid-template-columns:minmax(0,1fr)}
.feature-row.wide p{max-width:74ch}
.feature-row.flip .fig{order:-1}
@media (max-width:900px){.feature-row.flip .fig{order:0}}
.feature-row .n{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;color:var(--red);
  display:block;margin-bottom:14px;
}
.feature-row h2{font-size:clamp(24px,3vw,38px);line-height:1.06;letter-spacing:-.024em;margin-bottom:14px}
.feature-row p{color:var(--paper-2);font-size:16px;line-height:1.6;margin:0 0 12px;max-width:52ch}
.feature-row p:last-child{margin-bottom:0}
.fig{
  border-radius:10px;overflow:hidden;aspect-ratio:4/3;
  background:
    repeating-linear-gradient(0deg, rgba(237,232,224,.03) 0 1px, transparent 1px 3px),
    linear-gradient(168deg,#191920,#0F0F13 62%);
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
  display:grid;place-items:center;
}
.fig .cap{
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-3);
}
/* A figure holding a real picture is the shape of that picture.
   Empty, it stays a 4:3 well with the drawn plate in it. With an image, the
   4:3 box plus overflow:hidden simply cut the bottom off anything taller than
   it: a screenshot lost its meters, a page of a manual lost its last
   paragraph. The height is capped and the width follows, so a tall picture
   gets narrower rather than getting cut. */
.fig:has(img){
  aspect-ratio:auto;overflow:visible;display:block;
  background:none;box-shadow:none;
}
.fig img{
  display:block;margin:0 auto;
  width:auto;max-width:100%;height:auto;max-height:min(68vh,620px);
  border-radius:10px;
}

/* ---- demos --------------------------------------------------------------- */
.demos{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media (max-width:760px){.demos{grid-template-columns:1fr}}
.demo{
  display:flex;align-items:center;gap:14px;padding:14px 18px;border-radius:9px;
  background:var(--face);
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
.demo .go{
  width:34px;height:34px;border-radius:50%;flex:0 0 auto;display:grid;place-items:center;
  box-shadow:inset 0 0 0 1px var(--edge-hi);
}
.demo .go::before{
  content:"";width:0;height:0;margin-left:3px;
  border-left:9px solid var(--red);border-top:5.5px solid transparent;border-bottom:5.5px solid transparent;
}
.demo .t{min-width:0;flex:1}
.demo .t b{display:block;font-weight:500;font-size:14.5px;color:var(--paper);margin-bottom:7px}
.demo .bar{height:2px;border-radius:2px;background:var(--rule)}

/* ==========================================================================
   The page builder.
   A product page is not one form, it is an ordered list of sections. The admin
   picks which sections a plugin gets and what order they run in, and every
   section type is one we have already designed, so a page can be rearranged but
   never made to look like it belongs to another site.
   ========================================================================== */
.builder{display:grid;gap:10px}
.sect{
  border-radius:9px;overflow:hidden;
  background:linear-gradient(176deg,var(--ink-800),var(--ink-900));
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
  transition:opacity .2s ease;
}
.sect .bar{display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:center;padding:13px 16px}
/* The grip. Two columns of dots, which is what a grip has been since faders had
   knurling on them. */
.sect .grip{
  width:12px;height:18px;cursor:grab;flex:0 0 auto;
  background-image:radial-gradient(var(--paper-3) 1px, transparent 1.2px);
  background-size:5px 5px;background-position:0 2px;opacity:.5;
}
.sect .grip:active{cursor:grabbing}
.sect .what{min-width:0}
.sect .what b{
  display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--red);font-weight:400;margin-bottom:4px;
}
.sect .what span{display:block;font-size:14px;color:var(--paper-2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sect .ops{display:flex;gap:6px;align-items:center;flex:0 0 auto}
.sect.off{opacity:.42}
.sect.off .what b{color:var(--paper-3)}
/* A section the page cannot do without. It can be moved, not deleted. */
.sect.fixed .ops .rm{display:none}
.sect .lock{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);padding:0 4px;
}
.mini{
  font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--paper-2);
  padding:6px 10px;border-radius:6px;cursor:pointer;background:none;
  box-shadow:inset 0 0 0 1px var(--edge-hi);transition:.18s ease;
}
.mini:hover{color:var(--paper);box-shadow:inset 0 0 0 1px var(--paper-3)}
.mini.step{padding:6px 8px;line-height:1}
/* The open section shows its own fields underneath, in the same order they will
   appear on the page. */
.sect-body{padding:2px 16px 18px;border-top:1px solid var(--rule);margin-top:2px}
.sect-body .form{gap:12px;margin-top:16px}

/* Choosing a new section. Every option here is a section we have designed. */
.picker{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:14px}
@media (max-width:820px){.picker{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.picker{grid-template-columns:1fr}}
.pick{
  text-align:left;cursor:pointer;padding:14px 15px;border-radius:9px;background:none;
  box-shadow:inset 0 0 0 1px var(--edge-hi);transition:.2s ease;
}
.pick:hover{box-shadow:inset 0 0 0 1px var(--red-dim);transform:translateY(-1px)}
.pick b{
  display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--paper);font-weight:400;margin-bottom:6px;
}
.pick span{display:block;font-size:13px;color:var(--paper-3);line-height:1.45}


/* ==========================================================================
   Real pictures.
   A card keeps its 4:3 window so a row of them stays a row, and the artwork
   sits whole inside it rather than being cropped through its own title. On a
   product page there is no grid to keep, so the picture is simply itself.
   ========================================================================== */
.obj .shot.has-img{padding:10px}
.obj .shot.has-img img{width:100%;height:100%;object-fit:contain;border-radius:4px}
.hero-obj .shot.has-img{padding:16px}
/* The sleeve is taken out of the flow on purpose.
   In the flow, a 1005 pixel square reports 1005 pixels of height, the row grows
   to fit it, and the words beside it end up floating in the middle of a column
   twice their height. Positioned, it contributes no height at all: the words
   set the row, and the sleeve is a square of exactly that height, on the
   outside edge. The column keeps its width from the grid rather than from the
   picture, which is why the track is a fraction and not auto. */
.shot-big.has-img{
  aspect-ratio:auto;padding:0;background:none;box-shadow:none;overflow:visible;
  position:relative;height:100%;min-height:clamp(260px,26vw,420px);
}
.shot-big.has-img img{
  position:absolute;top:0;bottom:0;right:0;margin:auto 0 auto auto;
  display:block;height:100%;width:auto;max-width:100%;
  object-fit:contain;border-radius:10px;
}
@media (max-width:960px){
  .shot-big.has-img{position:static;height:auto;min-height:0}
  .shot-big.has-img img{position:static;height:auto;width:100%;margin:0 auto}
}
.line-item .mini.has-img{background:none;box-shadow:none}
.line-item .mini.has-img img{width:100%;height:100%;object-fit:contain}

/* ==========================================================================
   The dashboard.
   Two people share this, so anything that says "you" has to mean the person
   signed in, and anything that can go quietly wrong has to be visible without
   being looked for.
   ========================================================================== */
.dash-tabs{margin-bottom:20px}
.dash-tabs a{padding:10px 12px}

/* Health. Green is not a colour we own, so a working thing is simply quiet and
   a broken one is red. Nothing else needs a state. */
.checks{display:grid;gap:0}
.check{display:grid;grid-template-columns:auto 1fr auto;gap:14px;align-items:center;padding:13px 0;border-bottom:1px solid var(--rule)}
.check:last-child{border-bottom:0}
.check .dot{width:7px;height:7px;border-radius:50%;background:var(--paper-3);opacity:.55}
.check.bad .dot{background:var(--red);opacity:1;box-shadow:0 0 10px 1px rgba(212,52,42,.55)}
.check .txt{min-width:0}
.check .txt b{display:block;font-size:14.5px;font-weight:500;color:var(--paper);margin-bottom:2px}
.check .txt span{display:block;font-size:13px;color:var(--paper-3)}
.check.bad .txt span{color:var(--red-hot)}

/* A number with something under it, for money that belongs to one person. */
.mine{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
@media (max-width:700px){.mine{grid-template-columns:1fr}}
.mine .big{
  border-radius:10px;padding:22px;
  background:var(--face);
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
.mine .big .v{font-family:var(--mono);font-size:34px;font-variant-numeric:tabular-nums;letter-spacing:-.03em;color:var(--paper)}
.mine .big .k{font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-3);margin-top:8px}
.mine .big .sub{font-size:13px;color:var(--paper-3);margin-top:10px}

/* A bar in a table cell, for shares of a total. */
.bar-cell{display:grid;gap:6px;min-width:120px}
.bar-cell .t{display:flex;justify-content:space-between;font-family:var(--mono);font-size:12px}
.bar-cell .track{height:3px;border-radius:3px;background:var(--rule);overflow:hidden}
.bar-cell .fill{height:100%;background:var(--red);border-radius:3px}

/* Search above a table. */
.finder{display:flex;gap:10px;margin-bottom:16px;flex-wrap:wrap}
.finder input{
  flex:1;min-width:220px;font-family:var(--text);font-size:14.5px;color:var(--paper);
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:7px;padding:10px 13px;
}
.finder input:focus{outline:0;border-color:var(--red-dim);box-shadow:0 0 0 3px rgba(212,52,42,.13)}

.who{display:flex;align-items:center;gap:10px}
.who .av{
  width:26px;height:26px;border-radius:50%;flex:0 0 auto;
  background:var(--face);box-shadow:inset 0 0 0 1px var(--edge-hi);
  font-family:var(--mono);font-size:10px;display:grid;place-items:center;color:var(--paper-3);
}

/* ==========================================================================
   The affiliate panel.
   Somebody outside the company reads this, so every number that is not yet
   payable says why, and the rules are on a page of their own rather than in a
   PDF nobody opens.
   ========================================================================== */
/* A link, ready to be taken. Monospaced because it is a string, not prose. */
.copybox{display:flex;gap:8px;align-items:stretch;margin-top:8px}
.copybox code{
  flex:1;min-width:0;overflow-x:auto;white-space:nowrap;
  font-family:var(--mono);font-size:13.5px;color:var(--paper);
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:7px;padding:11px 13px;
}
.copybox .mini{flex:0 0 auto;padding:0 14px}
.linkrow{padding:16px 0;border-bottom:1px solid var(--rule)}
.linkrow:last-child{border-bottom:0;padding-bottom:0}
.linkrow b{display:block;font-size:14.5px;font-weight:500;color:var(--paper)}
.linkrow span.note{display:block;font-size:13px;color:var(--paper-3);margin-top:3px}

/* Artwork an affiliate can take and use. */
.assets{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
@media (max-width:820px){.assets{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.assets{grid-template-columns:1fr}}
.asset{border-radius:9px;overflow:hidden;background:var(--face);box-shadow:inset 0 0 0 1px var(--edge)}
.asset .pic{aspect-ratio:1/1;display:grid;place-items:center;padding:10px;background:var(--ink-900)}
.asset .pic img{width:100%;height:100%;object-fit:contain}
.asset .cap{padding:12px 14px;display:flex;align-items:center;justify-content:space-between;gap:10px}
.asset .cap b{font-size:13.5px;font-weight:500;color:var(--paper)}

/* A rule and its plain-English consequence, side by side. */
.rules{display:grid;gap:0}
.rule-row{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:24px;padding:16px 0;border-bottom:1px solid var(--rule)}
.rule-row:last-child{border-bottom:0}
@media (max-width:760px){.rule-row{grid-template-columns:1fr;gap:6px}}
.rule-row b{font-size:15px;font-weight:500;color:var(--paper)}
/* FIX: the name and the sentence under it ran together on one line, because a
   <b> is inline and nothing here made it a block. "Vinyl SimLands straight on
   the Vinyl Sim page." */
.rule-row .k b{display:block;margin-bottom:4px}
.rule-row .k span{display:block;font-size:13.5px;color:var(--paper-3);line-height:1.5}
.rule-row .copy{margin-top:0}
.rule-row .val{font-size:15px;color:var(--paper-2);line-height:1.55}
.rule-row .val em{font-style:normal;color:var(--red);font-family:var(--mono);font-size:14px}

/* ==========================================================================
   WooCommerce.
   Woo prints its own markup with its own class names, so this section dresses
   what it emits rather than replacing it. Everything here maps onto the same
   plates, the same red and the same mono capitals the rest of the site uses,
   so a customer never crosses a seam between "our pages" and "the shop".

   Several rules here are fixes, not decoration, and are marked as such: they
   are the layout faults that were found by using the site rather than by
   looking at it.
   ========================================================================== */

/* ---- shop listing -------------------------------------------------------- */
.woocommerce ul.products{
  display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,1.6vw,22px);
  list-style:none;padding:0;margin:0;
}
@media (max-width:1000px){.woocommerce ul.products{grid-template-columns:repeat(2,1fr)}}
@media (max-width:640px){.woocommerce ul.products{grid-template-columns:1fr}}
.woocommerce ul.products li.product{
  position:relative;margin:0;padding:0;text-align:left;overflow:hidden;border-radius:10px;
  background-image:var(--grime), var(--face);
  box-shadow:var(--lift),
             inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
  transition:transform .32s cubic-bezier(.2,.7,.2,1), box-shadow .32s ease, background .32s ease;
}
.woocommerce ul.products li.product:hover{
  transform:translateY(-3px);
  background-image:var(--grime), var(--face-hi);
  box-shadow:var(--lift-hi),
             inset 0 1px 0 var(--edge-hi), inset 1px 0 0 var(--edge-hi), inset -1px 0 0 var(--edge-hi);
}
/* A fixed window, so a row of cards stays a row whatever shape the artwork is.
   Contained rather than cropped: the sleeves carry their own titles across the
   top and filling a 4:3 window would cut straight through them. */
.woocommerce ul.products li.product a img{
  margin:0;display:block;width:100%;height:auto;
  aspect-ratio:var(--cover);object-fit:contain;background:var(--ink-900);padding:10px;
}
.woocommerce ul.products li.product .woocommerce-loop-product__title{
  font-family:var(--display);font-size:19px;font-weight:700;letter-spacing:-.022em;
  padding:18px 20px 0;margin:0;color:var(--paper);
}
.woocommerce ul.products li.product .price{
  display:block;padding:8px 20px 0;color:var(--paper);
  font-family:var(--mono);font-size:14px;font-variant-numeric:tabular-nums;
}
.woocommerce ul.products li.product .price del{color:var(--paper-3);opacity:1}
.woocommerce ul.products li.product .price ins{text-decoration:none;color:var(--paper)}
.woocommerce ul.products li.product .button{margin:16px 20px 20px}
/* Woo's own sale flash, made to match the New tag on our own cards. */
.woocommerce span.onsale{
  position:absolute;top:14px;left:14px;right:auto;z-index:2;margin:0;
  font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:#F6EDE6;background:var(--red);border-radius:3px;
  padding:5px 9px;min-height:0;min-width:0;line-height:1;
}

/* ---- single product ------------------------------------------------------ */
.woocommerce div.product .product_title{
  font-family:var(--display);font-size:clamp(30px,4vw,48px);font-weight:700;
  letter-spacing:-.026em;line-height:1.04;margin:0 0 14px;
}
.woocommerce div.product p.price,
.woocommerce div.product span.price{
  color:var(--paper);font-family:var(--mono);font-size:clamp(17px,1.9vw,22px);
  font-variant-numeric:tabular-nums;letter-spacing:-.02em;
}
.woocommerce div.product p.price del{color:var(--paper-3);opacity:1;font-size:.7em}
.woocommerce div.product p.price ins{text-decoration:none}
/* The follow-down bar keeps the compact card-size price, not the big
   product-page one, so it reads the same as the prices on the shop. */
.woocommerce div.product .prodbar .bar-buy .price{font-size:15px}
.woocommerce div.product .woocommerce-product-details__short-description{
  color:var(--paper-2);max-width:62ch;font-size:16.5px;line-height:1.6;
}
.woocommerce div.product .product_meta{
  font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);
}
.woocommerce div.product .product_meta a{color:var(--paper-2)}
.woocommerce div.product div.images img{border-radius:10px}

/* ---- buttons ------------------------------------------------------------- */
.woocommerce #respond input#submit,
.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--text);font-size:14px;font-weight:500;line-height:1.2;
  padding:11px 20px;border-radius:7px;cursor:pointer;transition:.2s ease;
  background:none;color:var(--paper);box-shadow:none;border:1px solid var(--edge-hi);
}
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce #respond input#submit:hover{
  background:none;border-color:var(--paper-3);color:var(--paper);
}
/* The one that takes money is the only red one on the page. */
.woocommerce a.button.alt,
.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce #respond input#submit.alt{
  background:linear-gradient(180deg,var(--red-hot),var(--red));color:#FFF;
  border:1px solid transparent;box-shadow:0 10px 24px -14px rgba(212,52,42,.85);
}
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover,
.woocommerce input.button.alt:hover{
  filter:brightness(1.06);transform:translateY(-1px);
  background:linear-gradient(180deg,var(--red-hot),var(--red));color:#FFF;
}
.woocommerce a.button.disabled,
.woocommerce button.button:disabled{opacity:.45;cursor:not-allowed;transform:none}

/* ---- forms --------------------------------------------------------------- */
/* FIX: Woo ships labels inline, which put every label beside its own field and
   made the widths disagree down the page. */
.woocommerce form .form-row{display:flex;flex-direction:column;margin-bottom:16px}
.woocommerce form .form-row label{
  display:block;font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--paper-3);margin-bottom:7px;
}
.woocommerce form .form-row .required{color:var(--red);text-decoration:none;border:0}
.woocommerce form .form-row input.input-text,
.woocommerce form .form-row textarea,
.woocommerce form .form-row select,
.woocommerce .select2-container .select2-selection--single{
  width:100%;font-family:var(--text);font-size:15px;color:var(--paper);
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:7px;
  padding:11px 13px;height:auto;transition:border-color .18s ease, box-shadow .18s ease;
}
.woocommerce form .form-row input.input-text:focus,
.woocommerce form .form-row textarea:focus,
.woocommerce form .form-row select:focus{
  outline:0;border-color:var(--red-dim);box-shadow:0 0 0 3px rgba(212,52,42,.13);
}
.woocommerce form .form-row textarea{min-height:120px;resize:vertical}
/* A checkbox is not a field: it must not be a column with a mono capital over
   it. Written long enough to outrank `.woocommerce form .form-row label`, which
   is three classes and would otherwise win and make this uppercase. */
.woocommerce form .form-row label.woocommerce-form__label-for-checkbox,
.woocommerce label.woocommerce-form__label-for-checkbox{
  display:flex;align-items:center;gap:9px;text-transform:none;letter-spacing:0;
  font-family:var(--text);font-size:14.5px;color:var(--paper-2);margin:0;
}
.woocommerce form .form-row label.woocommerce-form__label-for-checkbox input,
.woocommerce label.woocommerce-form__label-for-checkbox input{width:auto;margin:0}
.woocommerce-privacy-policy-text{color:var(--paper-3);font-size:13px}
.woocommerce-privacy-policy-text a{color:var(--red)}
.woocommerce .woocommerce-LostPassword{margin:14px 0 0}
.woocommerce .woocommerce-LostPassword a{color:var(--red)}
.woocommerce form.login,
.woocommerce form.register{
  border-radius:10px;padding:clamp(20px,2.4vw,30px);
  background:var(--face);
  box-shadow:var(--lift),
             inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
.woocommerce form.login .form-row:last-of-type{margin-bottom:0}
/* FIX: a plate inside a plate. The sign-in form carries its own plate for the
   case where Woo prints it on its own, and the theme's own template already
   puts it in a panel, so the page showed a box drawn inside a box. */
.panel form.login,
.panel form.register,
.panel .woocommerce form.login,
.panel .woocommerce form.register{background:none;box-shadow:none;padding:0;border-radius:0}
/* The form row is a column so its label sits above its field. A button is not a
   field, and stretching it to the width of the form makes Place order look like
   a banner rather than a button. */
.woocommerce form .form-row button,
.woocommerce form .form-row input[type="submit"],
.woocommerce form .form-row .button{align-self:flex-start}

/* FIX: Woo puts Login and Register in .u-columns, which floated them and left
   half the page empty on a wide screen. As a grid they are two equal halves. */
.woocommerce .u-columns#customer_login{
  display:grid;grid-template-columns:1fr 1fr;gap:clamp(18px,2.4vw,30px);
}
.woocommerce .u-columns#customer_login > div{min-width:0;float:none;width:auto}
@media (max-width:820px){.woocommerce .u-columns#customer_login{grid-template-columns:1fr}}
.woocommerce .u-columns#customer_login h2{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-3);font-weight:400;margin:0 0 14px;
}

/* ---- tables: cart, orders, downloads ------------------------------------- */
.woocommerce table.shop_table{
  border:0;border-collapse:collapse;width:100%;border-radius:0;
}
.woocommerce table.shop_table th{
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper-3);font-weight:400;text-align:left;
  padding:0 14px 11px 0;border-bottom:1px solid var(--rule);background:none;
}
.woocommerce table.shop_table td{
  border-top:0;border-bottom:1px solid var(--rule);padding:16px 14px 16px 0;
  color:var(--paper-2);vertical-align:middle;background:none;
}
.woocommerce table.shop_table tr:last-child td{border-bottom:0}
.woocommerce table.shop_table td.product-total + td,
.woocommerce table.shop_table th.product-total + th{padding-left:18px}
.woocommerce table.shop_table td.product-name a{color:var(--paper);font-weight:500}
.woocommerce table.shop_table .amount{
  font-family:var(--mono);color:var(--paper);font-variant-numeric:tabular-nums;
}
.woocommerce table.shop_table img{border-radius:6px}
.woocommerce .quantity .qty{
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:7px;
  color:var(--paper);padding:9px;font-family:var(--mono);width:64px;
}
.woocommerce-cart .cart-collaterals .cart_totals{
  border-radius:10px;padding:clamp(18px,2.2vw,26px);
  background:var(--face);
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
.woocommerce-cart .cart-collaterals .cart_totals h2{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-3);font-weight:400;margin:0 0 12px;
}
/* The line that says what you are about to pay, set apart from the ones above
   it, because it is the only number on the page anybody checks twice. */
.cart_totals .kv .order-total dt{color:var(--paper-2)}
.cart_totals .kv .order-total dd{font-size:22px;font-family:var(--mono);font-variant-numeric:tabular-nums}
/* Rows that only exist when there is a discount, a fee, or a tax line shown
   separately. They keep their own class names because payment and tax plugins
   hook onto them by name. */
.cart_totals .kv .fee dd,
.cart_totals .kv .tax-rate dd{color:var(--paper-2)}
.cart_totals .kv [class*="coupon-"] dd{color:var(--red)}
/* The row the checkout button sits in.
   align-items matters: this row is inside a column that is stretched to match
   the height of the cart beside it, so a row of default stretch handed all the
   leftover height to the button and drew a red slab a hundred pixels tall. */
.cart_totals .wc-proceed-to-checkout{margin-top:18px;display:flex;align-items:flex-start}
/* A button the width of the panel is a banner, and a banner is what made the
   two halves of the cart stop agreeing about where they end. It is the size of
   every other button on the site, and it says so in every direction. */
.woocommerce .cart_totals .wc-proceed-to-checkout .button,
.woocommerce .cart_totals .checkout-button{
  flex:0 0 auto;align-self:flex-start;justify-content:center;
  padding:11px 20px;font-size:14px;line-height:1.2;height:auto;min-height:0;
  border-radius:7px;white-space:nowrap;
}
/* The discount box. Without a rule of its own the browser drew its default
   white field in the middle of the cart. */
.woocommerce #coupon_code,
.woocommerce .coupon input.input-text{
  font-family:var(--text);font-size:14px;color:var(--paper);
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:7px;padding:10px 12px;
}
.woocommerce #coupon_code:focus{outline:0;border-color:var(--red-dim);box-shadow:0 0 0 3px rgba(212,52,42,.13)}
.woocommerce #coupon_code::placeholder{color:var(--paper-3)}

/* ---- checkout ------------------------------------------------------------ */
/* Checkout, two columns that start at the same line.
   WooCommerce's own markup is three siblings in one form: the details, a
   heading, and the order box. Left to itself that stacks the order under the
   details and squeezes it into whatever is left, which is how a payment form
   ends up half the width of the page with a hand's width of nothing beside it.
   Placed explicitly, the order box sits beside the details and its heading
   lines up with theirs. */
.woocommerce-checkout #customer_details,
.woocommerce-checkout #order_review,
.woocommerce-checkout #order_review_heading{max-width:none;width:auto;float:none}

@media (min-width:901px){
  .woocommerce-checkout form.checkout{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    grid-template-rows:auto 1fr;
    gap:clamp(20px,2.4vw,34px);
    align-items:start;
  }
  .woocommerce-checkout form.checkout > #customer_details{grid-area:1 / 1 / 3 / 2}
  .woocommerce-checkout form.checkout > #order_review_heading{grid-area:1 / 2 / 2 / 3;margin:0}
  .woocommerce-checkout form.checkout > #order_review{grid-area:2 / 2 / 3 / 3}
  /* Anything else Woo or a gateway drops into the form, a coupon notice or a
     login prompt, spans both rather than breaking the grid. */
  .woocommerce-checkout form.checkout > *:not(#customer_details):not(#order_review):not(#order_review_heading){
    grid-column:1 / -1;
  }
}

/* The details column's own two halves stop being floats as well. */
.woocommerce-checkout #customer_details .col-1,
.woocommerce-checkout #customer_details .col-2{float:none;width:auto}
.woocommerce-checkout #customer_details .col2-set{display:grid;gap:18px}
#add_payment_method #payment,
.woocommerce-cart #payment,
.woocommerce-checkout #payment{
  background:var(--face);border-radius:10px;
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
.woocommerce-checkout #payment div.payment_box{
  background:var(--ink-900);color:var(--paper-2);border-radius:8px;
}
.woocommerce-checkout #payment div.payment_box::before{border-bottom-color:var(--ink-900)}
.woocommerce-checkout #payment ul.payment_methods{border-bottom:1px solid var(--rule)}
.woocommerce-checkout #payment ul.payment_methods li{color:var(--paper-2)}

/* ---- my account ---------------------------------------------------------- */
/* The account screens are the theme's own templates now, so the sections are a
   tab row like every other panel on the site rather than a floated sidebar.
   The old sidebar rules are gone: they were what kept the navigation stacked
   down the left and the content squeezed into half the page. */
.woocommerce-account .woocommerce{display:block}
.woocommerce-MyAccount-navigation{
  display:flex;gap:6px;flex-wrap:wrap;margin:0 0 22px;padding:0;list-style:none;
  border-bottom:1px solid var(--rule);
}
.woocommerce-MyAccount-navigation ul{display:contents;list-style:none;margin:0;padding:0}
.woocommerce-MyAccount-navigation li{list-style:none;margin:0;padding:0;border:0}
.woocommerce-MyAccount-navigation a{
  font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);padding:12px 14px;display:block;position:relative;transition:color .18s ease;
}
.woocommerce-MyAccount-navigation a:hover{color:var(--paper-2)}
.woocommerce-MyAccount-navigation a.on,
.woocommerce-MyAccount-navigation li.is-active a{color:var(--red)}
.woocommerce-MyAccount-navigation a.on::after,
.woocommerce-MyAccount-navigation li.is-active a::after{
  content:"";position:absolute;inset:auto 10px -1px;height:1px;background:var(--red);
}
.woocommerce-MyAccount-content{max-width:none;min-width:0}
.woocommerce-MyAccount-content > h2:first-child,
.woocommerce-MyAccount-content > h1:first-child{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-3);font-weight:400;margin:0 0 16px;
}

/* ---- notices ------------------------------------------------------------- */
.note{
  border-radius:8px;padding:14px 16px;font-size:14.5px;color:var(--paper-2);
  box-shadow:inset 0 0 0 1px var(--edge-hi);background:rgba(237,232,224,.02);
}
.note.red{box-shadow:inset 0 0 0 1px var(--red-dim)}
.note strong{color:var(--paper)}
.empty{padding:34px 0;text-align:center;color:var(--paper-3);font-size:15px}

/* ==========================================================================
   Two things that have to be true on every page.
   ========================================================================== */

/* 1. A jump link scrolls. It does not leap.
      Both bars are sticky, so an anchor that lands at the top of the viewport
      lands underneath them and the heading you asked for is the one thing you
      cannot see. The offset is the masthead plus the product bar plus air. */
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
section[id],div[id].prodbar,.band[id],.page[id]{scroll-margin-top:calc(68px + 60px + 24px)}
/* Pages with no product bar only have the masthead to clear. */
body:not(.single-product) section[id],
body:not(.single-product) .band[id]{scroll-margin-top:calc(68px + 24px)}

/* 2. Buttons standing next to each other are the same height.
      A row of actions mixes our own .btn with the button WooCommerce prints,
      and those two arrived with different padding and different font sizes, so
      one sat taller than the other. Everything in a row is now driven from the
      same three numbers, and the form Woo wraps its button in is flattened so
      it cannot add a box of its own. */
.ctas,.actions{align-items:stretch}
.ctas form.cart,.actions form.cart{display:flex;margin:0;padding:0}
.ctas .btn,
.ctas .button,
.woocommerce .ctas .button,
.woocommerce .ctas button.button,
.woocommerce .ctas .single_add_to_cart_button{
  display:inline-flex;align-items:center;justify-content:center;
  padding:14px 22px;font-size:15px;line-height:1.2;border-radius:8px;margin:0;
}
.actions .btn,
.woocommerce .actions .button,
.woocommerce .actions button.button{
  display:inline-flex;align-items:center;justify-content:center;
  padding:11px 20px;font-size:14px;line-height:1.2;border-radius:7px;margin:0;
}
/* Woo's quantity box sits in the same row on some products. Match the height so
   the row does not step up and down across it. */
.woocommerce .ctas .quantity .qty{padding:14px 12px;border-radius:8px}

/* ==========================================================================
   Section kinds a product page can be built from, beyond the ones the front
   page already uses. Each is drawn by one branch of the theme's renderer and
   offered by one entry in the dashboard's picker: that pair is the only thing
   deciding what a page can be arranged into.
   ========================================================================== */

/* A line from a review, set large enough to be the only thing in its band. */
.pull{margin:0;max-width:70ch}
.pull blockquote{
  margin:0;font-family:var(--display);font-weight:700;letter-spacing:-.024em;
  font-size:clamp(22px,3vw,36px);line-height:1.18;color:var(--paper);
}
.pull blockquote::before{content:"\201C"}
.pull blockquote::after{content:"\201D"}
.pull figcaption{
  margin-top:16px;font-family:var(--mono);font-size:11px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--red);
}

/* An audio demo with a real file behind it. The native player is left alone
   apart from its width: a hand-built transport that cannot be operated from a
   keyboard is worse than a plain one. */
.demo audio{width:100%;height:32px;display:block;margin-top:4px}
.demo .t{min-width:0;flex:1}

/* Screenshots in a gallery reuse the figure well from the feature rows, but
   without a forced shape, because a screenshot is whatever shape it is. */
.grid > .fig{aspect-ratio:auto}
.grid > .fig img{width:100%;height:auto;display:block;border-radius:10px}

/* ==========================================================================
   The demo video.
   Sits in the same well as everything else, and on youtube-nocookie so a
   visitor is not tracked for looking at a plugin.
   ========================================================================== */
.ptf-demo{margin:clamp(28px,4vw,44px) 0}
.ptf-demo .frame{
  position:relative;aspect-ratio:16/9;border-radius:10px;overflow:hidden;
  background:linear-gradient(176deg,var(--ink-800),var(--ink-900));
  box-shadow:inset 0 0 0 1px var(--edge);
}
.ptf-demo .frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}


/* ==========================================================================
   The affiliate panel and the maps.
   Eight screens on the site itself rather than in the owner's dashboard, so an
   affiliate keeps the masthead, the breadcrumb and the footer, and never lands
   anywhere that looks like somebody's admin.
   ========================================================================== */

.ptf-affiliate .tabs{margin-bottom:22px}
.ptf-affiliate .stats{margin-bottom:18px}
.ptf-affiliate .panel + .panel{margin-top:18px}
.ptf-affiliate .cols{margin-top:18px}
.ptf-affiliate .panel .said + .copy{margin-top:14px}
.ptf-affiliate .muted{color:var(--paper-3)}

/* A link, and the button that copies it. The field is the width of the panel
   because a truncated link is worse than no link: it looks like the whole one. */
.copy{display:flex;gap:10px;align-items:stretch;margin-top:12px}
.copy input{
  flex:1;min-width:0;font-family:var(--mono);font-size:13.5px;color:var(--paper);
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:7px;
  padding:11px 13px;overflow-x:auto;
}
.copy input:focus{outline:0;border-color:var(--red-dim);box-shadow:0 0 0 3px rgba(212,52,42,.13)}
.copy .btn{flex:none;padding:11px 18px;font-size:14px}
.copy .btn.copied{color:var(--red);border-color:var(--red-dim)}

/* Artwork on the assets screen: the caption carries the download button, so the
   row of tiles has one baseline whatever shape the artwork is. */
.asset{margin:0;min-width:0}
.asset img{
  display:block;width:100%;height:auto;aspect-ratio:var(--cover);object-fit:contain;
  background:var(--ink-900);border-radius:10px;padding:10px;
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
.asset .none{
  display:grid;place-items:center;aspect-ratio:var(--cover);border-radius:10px;background:var(--ink-900);
  font-family:var(--mono);font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-3);
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
.asset figcaption{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:12px 2px 0;font-size:14.5px;color:var(--paper);
}
.asset figcaption .btn{padding:8px 14px;font-size:13px;flex:none}

/* ---- the world ----------------------------------------------------------- */
/* Equal Earth projection, drawn from Natural Earth outlines, shipped with the
   plugin. Four steps of red rather than a gradient: a country either sold
   something or it did not, and a smooth ramp makes one sale look like none. */
.wmap-wrap{position:relative;margin:6px 0 18px}
.wmap-holder{border-radius:10px;overflow:hidden;background:var(--ink-900);padding:8px 0}
.wmap{display:block;width:100%;height:auto}
.wmap .lands path{fill:#151519;stroke:var(--ink-900);stroke-width:.6;transition:fill .15s ease}
.wmap .lands path.lit.s1{fill:rgba(212,52,42,.28)}
.wmap .lands path.lit.s2{fill:rgba(212,52,42,.48)}
.wmap .lands path.lit.s3{fill:rgba(212,52,42,.72)}
.wmap .lands path.lit.s4{fill:var(--red)}
.wmap .lands path:hover{fill:var(--red-hot)}

.wmap-tip{
  position:absolute;z-index:3;pointer-events:none;min-width:130px;max-width:260px;
  background:var(--ink-850);border-radius:8px;padding:10px 12px;
  box-shadow:0 18px 40px -22px #000, inset 0 0 0 1px var(--edge-hi);
}
.wmap-tip[hidden]{display:none}
.wmap-tip b{display:block;color:var(--paper);font-size:14px;font-weight:600;margin-bottom:3px}
.wmap-tip .n{display:block;font-family:var(--mono);font-size:12px;color:var(--red)}
.wmap-tip .c{display:block;margin-top:5px;font-size:12px;color:var(--paper-3);line-height:1.4}
.wmap-tip .c:empty{display:none}

.wmap-key{display:flex;align-items:center;gap:6px;margin-top:10px}
.wmap-key span{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--paper-3)}
.wmap-key i{width:26px;height:8px;border-radius:2px;display:block}
.wmap-key .s1{background:rgba(212,52,42,.28)}
.wmap-key .s2{background:rgba(212,52,42,.48)}
.wmap-key .s3{background:rgba(212,52,42,.72)}
.wmap-key .s4{background:var(--red)}

/* ---- the line across the top of Analytics -------------------------------- */
/* Bars rather than a line: a line between two days implies the traffic went
   through the values in between, and it did not. */
.spark{display:flex;align-items:flex-end;gap:2px;height:120px;margin:4px 0 6px}
.spark .d{flex:1;min-width:0;background:rgba(212,52,42,.35);border-radius:2px 2px 0 0;position:relative;transition:background .15s ease}
.spark .d:hover{background:var(--red)}
.spark .d span{
  position:absolute;bottom:100%;left:50%;transform:translateX(-50%);margin-bottom:6px;
  white-space:nowrap;font-family:var(--mono);font-size:11px;color:var(--paper);
  background:var(--ink-850);border-radius:6px;padding:5px 8px;opacity:0;pointer-events:none;
  box-shadow:inset 0 0 0 1px var(--edge-hi);
}
.spark .d:hover span{opacity:1}
.spark-axis{display:flex;justify-content:space-between;font-family:var(--mono);font-size:10px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--paper-3)}

/* ---- a bar in a table row ------------------------------------------------ */
/* For "which page, how much of the total". The bar is behind the number rather
   than beside it, so the column stays a column. */
.tbl td .bar{display:block;height:3px;border-radius:2px;background:var(--red);opacity:.55;margin-top:6px}

/* ---- the date range ------------------------------------------------------ */
.range{display:flex;gap:6px;flex-wrap:wrap;margin:0 0 18px}
.range a{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);padding:8px 12px;border-radius:6px;box-shadow:inset 0 0 0 1px var(--edge);
}
.range a:hover{color:var(--paper-2)}
.range a.on{color:var(--red);box-shadow:inset 0 0 0 1px var(--red-dim)}

/* A section shown ten at a time, and the way into the whole of it.
   Set quietly at the foot of the panel: it is a door, not an argument. */
.more{
  display:inline-block;margin-top:14px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);transition:color .18s ease;
}
.more:hover{color:var(--red)}
.more::after{content:"\00a0\2192"}

/* And the way back out of it, above the title of the section you are in. */
.back{margin:0 0 14px}
.back a{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);transition:color .18s ease;
}
.back a:hover{color:var(--red)}
.back a::before{content:"\2190\00a0"}

/* The head of one section's own page. Smaller than a page title, because the
   page already has one. */
.head h2{font-size:clamp(22px,2.6vw,32px);line-height:1.06;letter-spacing:-.022em;margin-bottom:10px}

/* A thing that is usually in the way, folded shut. The summary is the whole
   control: no script, and it survives a page with no JavaScript at all. */
.fold{margin:0 0 18px}
.fold > summary{
  cursor:pointer;list-style:none;display:inline-flex;align-items:center;gap:8px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);padding:9px 13px;border-radius:7px;box-shadow:inset 0 0 0 1px var(--edge);
  transition:color .18s ease, box-shadow .18s ease;
}
.fold > summary::-webkit-details-marker{display:none}
.fold > summary::before{content:"+";font-size:13px;line-height:1}
.fold[open] > summary::before{content:"\2212"}
.fold > summary:hover{color:var(--paper);box-shadow:inset 0 0 0 1px var(--edge-hi)}
.fold > .panel{margin-top:12px}

.pager{display:flex;gap:6px;flex-wrap:wrap;margin:18px 0 0}
.pager a{
  font-family:var(--mono);font-size:12px;color:var(--paper-3);
  padding:6px 10px;border-radius:6px;box-shadow:inset 0 0 0 1px var(--edge);
  transition:color .18s ease, box-shadow .18s ease;
}
.pager a:hover{color:var(--paper)}
.pager a.on{color:var(--red);box-shadow:inset 0 0 0 1px var(--red-dim)}


/* ==========================================================================
   The section builder.
   A product page is an ordered list of sections, and this is the list. None of
   these class names had a single rule against them: the whole builder was
   drawn by the browser's defaults, which is why the rows did not look like
   rows and there was nothing to click.
   ========================================================================== */

.build{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,300px);gap:24px;align-items:start}
@media (max-width:1000px){.build{grid-template-columns:1fr}}

.sect-list{display:grid;gap:10px}

.sect{
  border-radius:9px;overflow:hidden;background:var(--face);
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge),
             inset -1px 0 0 var(--edge), inset 0 -1px 0 var(--edge);
  transition:box-shadow .18s ease, opacity .18s ease;
}
.sect:hover{box-shadow:inset 0 0 0 1px var(--edge-hi)}
/* Hidden means kept but not printed. Greyed, never removed from the list, so
   you can see what is being left out. */
.sect.off{opacity:.5}
.sect.off .sect-t b::after{
  content:"Hidden";margin-left:9px;font-family:var(--mono);font-size:9px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--red);
}
.sect.dragging{opacity:.35}
.sect.over{box-shadow:inset 0 0 0 1px var(--red-dim)}

.sect-bar{display:flex;align-items:center;gap:12px;padding:12px 14px;cursor:pointer;user-select:none}
/* Three lines, the way a handle is knurled. The bar is what starts a drag,
   and this is the part of it that says so. */
.grip{
  flex:none;width:12px;height:14px;cursor:grab;
  background-image:linear-gradient(var(--paper-3) 1px, transparent 1px);
  background-size:12px 4px;background-position:0 2px;background-repeat:repeat-y;
  opacity:.45;transition:opacity .18s ease;
}
.sect-bar:hover .grip{opacity:.85}
.grip:active{cursor:grabbing}

.sect-t{flex:1;min-width:0}
.sect-t b{display:block;font-size:14.5px;font-weight:500;color:var(--paper);line-height:1.3}
/* The line under the name: what the section is, then what it is holding.
   Only the description is allowed to run out of room, so the count of pictures
   is still there on a row whose heading is a paragraph long. */
.sect-t .line{display:flex;align-items:baseline;gap:10px;min-width:0;margin-top:2px}
.sect-t .what{
  font-size:12.5px;color:var(--paper-3);line-height:1.4;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.sect-t .holds{
  flex:none;font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--paper-3);
}
.sect-ops{display:flex;align-items:center;gap:6px;flex:none}
.sect-ops .btn{
  padding:6px 10px;font-size:12px;border-radius:6px;background:none;color:var(--paper-2);
  box-shadow:none;border:1px solid var(--edge-hi);
}
.sect-ops .btn:hover{border-color:var(--paper-3);color:var(--paper);transform:none;filter:none}
.sect-ops .btn.up,
.sect-ops .btn.down{padding:6px 9px;font-family:var(--mono);line-height:1}
.sect-ops .btn.rm:hover{border-color:var(--red-dim);color:var(--red-hot)}
.sect-ops .lock{
  font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--paper-3);padding:0 4px;
}

/* Closed until you open it, and opening one does not close the others. */
.sect-body{display:none;padding:2px 14px 16px;border-top:1px solid var(--rule)}
.sect.open .sect-body{display:grid;gap:4px}

.s-lab{
  display:block;font-family:var(--mono);font-size:10px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--paper-3);margin:14px 0 6px;
}
.sect-body .s-f,
.sect-body input[type="text"],
.sect-body input:not([type]),
.sect-body textarea,
.sect-body select{
  width:100%;font-family:var(--text);font-size:14.5px;color:var(--paper);
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:7px;
  padding:10px 12px;transition:border-color .18s ease, box-shadow .18s ease;
}
.sect-body textarea{min-height:84px;resize:vertical;line-height:1.5}
.sect-body .s-f:focus,
.sect-body textarea:focus,
.sect-body select:focus{outline:0;border-color:var(--red-dim);box-shadow:0 0 0 3px rgba(212,52,42,.13)}
.sect-body select{
  -webkit-appearance:none;appearance:none;cursor:pointer;padding-right:38px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'><path d='M1 1.2 5.5 5.7 10 1.2' fill='none' stroke='%23D4342A' stroke-width='1.6' stroke-linecap='square'/></svg>");
  background-repeat:no-repeat;background-position:right 14px center;background-size:11px 7px;
}

/* Choosing a picture is choosing a file. Never an id typed into a box. */
.s-file{
  display:block;width:100%;font-family:var(--text);font-size:13px;color:var(--paper-3);
  background:var(--ink-900);border:1px dashed var(--edge-hi);border-radius:7px;padding:10px 12px;
  cursor:pointer;
}
.s-file:hover{border-color:var(--red-dim);color:var(--paper-2)}
.s-file::file-selector-button{
  font-family:var(--text);font-size:12.5px;color:var(--paper);background:none;
  border:1px solid var(--edge-hi);border-radius:6px;padding:6px 12px;margin-right:12px;cursor:pointer;
}
.s-file::file-selector-button:hover{border-color:var(--paper-3)}

.s-thumbs{display:flex;flex-wrap:wrap;gap:8px;margin:2px 0 8px}
.s-thumb{
  position:relative;display:inline-flex;align-items:center;gap:10px;margin:2px 0 8px;
  padding:8px;border-radius:8px;background:var(--ink-900);
  box-shadow:inset 0 0 0 1px var(--edge);
}
.s-thumbs .s-thumb{margin:0;padding:0}
.s-thumb img{display:block;width:64px;height:64px;object-fit:cover;border-radius:6px}
.s-thumb .btn.s-drop{padding:6px 10px;font-size:12px;background:none;box-shadow:none;border:1px solid var(--edge-hi);color:var(--paper-2)}
.s-thumbs .s-thumb .btn.s-drop-one{
  position:absolute;top:-6px;right:-6px;width:20px;height:20px;padding:0;border-radius:50%;
  display:grid;place-items:center;font-size:13px;line-height:1;
  background:var(--red);color:#FFF;border:0;box-shadow:none;
}

/* ---- the running order, beside the list ---------------------------------- */
.prev{
  border-radius:10px;padding:16px;position:sticky;top:88px;
  background:var(--face);
  box-shadow:inset 0 1px 0 var(--edge), inset 1px 0 0 var(--edge), inset -1px 0 0 var(--edge);
}
.prev h4{
  font-family:var(--mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-3);font-weight:400;margin:0 0 10px;
}
.prev .shot{
  border-radius:8px;overflow:hidden;aspect-ratio:3/4;background:var(--ink-900);
  box-shadow:inset 0 0 0 1px var(--edge);
}
/* The real page at a third of its size, not a drawing of one. */
.prev .shot iframe{
  width:300%;height:300%;border:0;display:block;
  transform:scale(.3333);transform-origin:0 0;pointer-events:none;
}
.prev ol{list-style:none;margin:0;padding:0;counter-reset:sect}
.prev ol li{
  counter-increment:sect;display:grid;grid-template-columns:auto 1fr;gap:10px;
  padding:8px 0;border-bottom:1px solid var(--rule);align-items:baseline;
}
.prev ol li:last-child{border-bottom:0}
.prev ol li::before{
  content:counter(sect);font-family:var(--mono);font-size:10px;color:var(--red);
  font-variant-numeric:tabular-nums;
}
.prev ol li b{font-size:13px;font-weight:500;color:var(--paper);display:block}
.prev ol li span{display:block;font-size:11.5px;color:var(--paper-3)}
.prev ol li.off{opacity:.45}
.prev ol li .h{color:var(--red);font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;text-transform:uppercase}

/* ==========================================================================
   Small classes the markup uses that had no rules of their own.
   ========================================================================== */

/* Used all over the two panels for a date, a code or an id. It was defined
   inside the dashboard's own <style> only, so every one of these on a site
   page — the whole affiliate panel — was printed in the body face. */
.mono{font-family:var(--mono);font-size:12.5px;font-variant-numeric:tabular-nums}
.muted{color:var(--paper-3)}

/* The first thing in the document, for anybody on a keyboard. Off screen until
   it is focused, which is the only time it is any use. */
.skip{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--red);color:#FFF;padding:10px 16px;border-radius:0 0 7px 0;
  font-size:14px;
}
.skip:focus{left:0}

/* The number beside Cart in the masthead. */
.site-head .cart .count{font-family:var(--mono);font-size:12px;color:var(--paper-3);font-variant-numeric:tabular-nums}
.site-head .cart:hover .count{color:var(--red)}

/* Taking a line out of the cart. A cross, not a word, and red only on hover so
   a page of them does not look like a page of warnings. */
.woocommerce a.remove{
  display:inline-block;color:var(--paper-3);font-size:13.5px;line-height:1.4;
  text-decoration:none;transition:color .18s ease;
}
.woocommerce a.remove:hover{color:var(--red-hot)}

/* Pagination under the catalogue. */
.woo-pages{display:block}

/* The payout run, printed as it was written. It is a report meant to be read
   line by line before any money moves, so it keeps its own line breaks. */
.report{
  margin:14px 0 0;padding:16px;border-radius:8px;overflow-x:auto;
  background:var(--ink-900);box-shadow:inset 0 0 0 1px var(--edge);
  font-family:var(--mono);font-size:12.5px;line-height:1.65;color:var(--paper-2);
  white-space:pre-wrap;word-break:break-word;
}

/* Why a payment failed, hung under the payment it failed on rather than
   sitting in the list as though it were another payment. */
.tbl tr.why td{
  padding-top:0;padding-bottom:14px;color:var(--red-hot);font-size:13px;
  border-bottom:1px solid var(--rule);
}
.tbl tr.why + tr td{border-top:0}

/* The fee field on a sale that is waiting for one. Sits inside a table cell, so
   it has to stay on one line and not stretch the column. */
.fee-form{display:flex;gap:8px;align-items:center;margin:0}
.fee-form input{
  width:84px;font-family:var(--mono);font-size:13px;color:var(--paper);
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:6px;padding:8px 10px;
}
/* The same control the rest of the site uses, not the browser's. A native
   select in the middle of a dark panel is the one thing that always gives the
   game away. */
.fee-form select{
  -webkit-appearance:none;appearance:none;cursor:pointer;
  font-family:var(--text);font-size:13px;color:var(--paper);
  background-color:var(--ink-900);border:1px solid var(--edge-hi);border-radius:6px;
  padding:8px 30px 8px 10px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'><path d='M1 1.2 5.5 5.7 10 1.2' fill='none' stroke='%23D4342A' stroke-width='1.6' stroke-linecap='square'/></svg>");
  background-repeat:no-repeat;background-position:right 10px center;background-size:9px 6px;
}
.fee-form select:hover{border-color:var(--red-dim)}
.fee-form input:focus,
.fee-form select:focus{outline:0;border-color:var(--red-dim);box-shadow:0 0 0 3px rgba(212,52,42,.13)}
.fee-form .btn{padding:8px 12px;font-size:12.5px;flex:none}
.fee-form .pill{flex:none}

/* Recovery codes, shown once. Set in the mono face at a size that survives
   being written on paper and read back at three in the morning. */
.codes{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;margin-top:16px;
}
.codes span{
  font-family:var(--mono);font-size:15px;letter-spacing:.06em;color:var(--paper);
  background:var(--ink-900);border-radius:7px;padding:12px 14px;text-align:center;
  box-shadow:inset 0 0 0 1px var(--edge-hi);
}

/* The rows on the security check. The dot is the state, the pill repeats it in
   a word, because a colour on its own is not something everybody can read. */
.checks .check .pill{margin-left:auto}

/* ==========================================================================
   Signing in.
   The panel's own sign-in page and the screen that asks for a code. Narrow,
   centred, and nothing else on it. These fields were drawn by the browser
   because the only rules for them lived inside the panel's own <style>, which
   styles labels and buttons and never got as far as the inputs.
   ========================================================================== */

.login h1{font-size:clamp(26px,3.4vw,38px);line-height:1.05;margin-bottom:10px}
.login .said{color:var(--paper-2);font-size:15.5px;line-height:1.6;max-width:56ch}
.login .note{margin:16px 0 0}
.login .panel{margin-top:18px}

.login input[type="text"],
.login input[type="email"],
.login input[type="password"],
.login input:not([type]){
  width:100%;font-family:var(--text);font-size:15px;color:var(--paper);
  background:var(--ink-900);border:1px solid var(--edge-hi);border-radius:7px;
  padding:11px 13px;transition:border-color .18s ease, box-shadow .18s ease;
}
.login input:focus{outline:0;border-color:var(--red-dim);box-shadow:0 0 0 3px rgba(212,52,42,.13)}

/* A six-digit code is read back off a phone one character at a time, so it is
   set in the mono face with room between the figures. */
.login input#ptf-code{
  font-family:var(--mono);font-size:20px;letter-spacing:.22em;text-align:center;padding:13px;
}

/* The shared key is forty characters. In a row beside a button it was cut off
   halfway through, which for a key is the same as not showing it. */
.login .copy{flex-wrap:wrap}
.login .copy input,
.login .copy textarea.key{
  flex:1 1 100%;font-family:var(--mono);font-size:15px;letter-spacing:.1em;
  text-align:center;overflow-wrap:anywhere;
}
.login .copy textarea.key{
  width:100%;color:var(--paper);background:var(--ink-900);
  border:1px solid var(--edge-hi);border-radius:7px;padding:12px 13px;
  resize:none;line-height:1.7;
}
.login .copy textarea.key:focus{outline:0;border-color:var(--red-dim);box-shadow:0 0 0 3px rgba(212,52,42,.13)}
.login .copy .btn{margin-left:auto}

/* The way into the panel, shown only to an account that has one. Marked in the
   red so it reads as ours rather than as another shop link, and never drawn at
   all for a customer or a stranger. */
.site-head .nav a.panel-link{color:var(--red)}
.site-head .nav a.panel-link:hover{color:var(--red-hot)}

/* ==========================================================================
   The buy band.
   The price and the button read as one thing, on one line, at the left of the
   column they share. The price used to sit centred with the button under it,
   which put the only control on the page in the middle of nowhere.
   ========================================================================== */

/* The price and the button sit at the right edge of the panel, level with the
   name on the left. Left-aligned inside their own column they stopped halfway
   across, which read as a gap in the middle rather than a row. */
.buy .cols.two{align-items:center}
.buy .buy-now{display:flex;align-items:center;justify-content:flex-end;gap:clamp(16px,2vw,26px);flex-wrap:wrap}
.buy .buy-now .price{margin:0}
.buy .buy-now .ctas{margin:0}
@media (max-width:620px){
  .buy .buy-now{gap:14px;justify-content:flex-start}
  .buy .buy-now .ctas{width:100%}
  .buy .buy-now .ctas form.cart,
  .buy .buy-now .ctas .button{width:100%;justify-content:center}
}

/* ==========================================================================
   The video row.
   The film and the words beside it end level. A video has one shape and cannot
   be stretched without either letterboxing it or cutting the picture, so the
   words are centred against it instead: no dead space under either column.
   ========================================================================== */

.band .cols.side:has(.ptf-demo){align-items:center}
.band .cols.side > .prose{align-self:center}

/* What the button just did, said beside the button. */
.added{
  margin:12px 0 0;font-size:14px;color:var(--paper-2);
  transition:opacity .4s ease;
}
.added a{color:var(--red);margin-left:2px}
.added.gone{opacity:0}

/* ==========================================================================
   The reel.
   Screenshots and manual pages, one at a time. Every slide sits in the same
   grid cell, so the box is as tall as the tallest picture and does not jump as
   it turns, and nothing is cropped: a picture is drawn whole, at its own shape,
   inside that box.
   ========================================================================== */

.shot-one{margin:0}
.shot-one img{
  display:block;width:auto;max-width:100%;height:auto;max-height:min(72vh,720px);
  margin:0 auto;border-radius:10px;background:var(--ink-900);
}

.reel{position:relative;border-radius:10px;background:var(--ink-900);
  box-shadow:inset 0 0 0 1px var(--edge);padding:14px}
/* The box is the shape of the picture in it.
   Only the slide being shown is in the flow, so the box takes that picture's
   own height: a wide screenshot gets a wide box and a page of a manual gets a
   tall one, and neither is padded out to the size of the other. */
.reel .slides{position:relative}
.reel .slide{
  position:absolute;inset:0;margin:0;display:grid;place-items:center;
  opacity:0;visibility:hidden;transition:opacity .4s ease;
}
.reel .slide.on{position:relative;inset:auto;opacity:1;visibility:visible}
.reel .slide img{
  display:block;width:auto;max-width:100%;height:auto;max-height:72vh;
  border-radius:6px;
}

/* The arrows sit over the picture and only darken what is under them. */
.reel-go{
  position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:42px;height:42px;border-radius:50%;border:0;cursor:pointer;
  background:rgba(9,9,10,.62);backdrop-filter:blur(4px);
  box-shadow:inset 0 0 0 1px var(--edge-hi);
  transition:background .18s ease, box-shadow .18s ease;
}
.reel-go:hover{background:rgba(9,9,10,.85);box-shadow:inset 0 0 0 1px var(--red-dim)}
.reel-go:focus-visible{outline:2px solid var(--red);outline-offset:2px}
.reel-go.prev{left:18px}
.reel-go.next{right:18px}
/* A chevron drawn rather than typed, so it is the same weight either way. */
.reel-go::before{
  content:"";position:absolute;top:50%;left:50%;width:9px;height:9px;
  border-left:1.6px solid var(--paper);border-bottom:1.6px solid var(--paper);
}
.reel-go.prev::before{transform:translate(-40%,-50%) rotate(45deg)}
.reel-go.next::before{transform:translate(-60%,-50%) rotate(-135deg)}

.reel .dots{display:flex;justify-content:center;gap:8px;margin-top:14px}
.reel .dot{
  width:7px;height:7px;border-radius:50%;border:0;padding:0;cursor:pointer;
  background:var(--paper-3);opacity:.4;transition:opacity .18s ease, background .18s ease;
}
.reel .dot:hover{opacity:.8}
.reel .dot.on{background:var(--red);opacity:1}

/* ==========================================================================
   What owners say.
   Three reviews across, because three is what fits at a size somebody will
   actually read. A fourth turns the row into a carousel rather than making the
   type smaller or starting a second row nobody scrolls to.
   ========================================================================== */

.says{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px;align-items:stretch}
@media (max-width:1000px){.says{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:680px){.says{grid-template-columns:1fr}}

.say{
  margin:0;padding:20px;border-radius:10px;background:var(--face);
  box-shadow:inset 0 0 0 1px var(--edge);
  display:grid;grid-template-rows:auto 1fr auto;gap:14px;
}
.say .top{display:flex;align-items:center;justify-content:space-between;gap:12px}
.say .when{font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;color:var(--paper-3)}
.say blockquote{
  margin:0;font-size:15px;line-height:1.62;color:var(--paper-2);
  /* Long words in a language with them, and pasted URLs, stay inside the card. */
  overflow-wrap:anywhere;
}
.say figcaption{
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  font-size:14px;color:var(--paper);
  padding-top:12px;border-top:1px solid var(--rule);
}
/* Not a badge with a tick in it. Everybody here bought it, so it is a fact
   printed quietly rather than a claim being made loudly. */
.say .own{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--paper-3)}

/* Five marks, of which some are lit. Drawn rather than typed, so they are the
   same weight on every machine and there is no font to wait for. */
.stars{display:inline-flex;gap:3px;vertical-align:middle}
.star{
  width:12px;height:12px;flex:none;background:var(--paper-3);opacity:.28;
  clip-path:polygon(50% 0,61.8% 34.5%,98% 34.5%,68.2% 57.3%,79.4% 100%,50% 71.5%,20.6% 100%,31.8% 57.3%,2% 34.5%,38.2% 34.5%);
}
.star.on{background:var(--red);opacity:1}
/* An average is not a whole number of stars. The lit row sits over the dim one
   and is cut off at the fraction, so four and a half looks like four and a
   half rather than being rounded up into a fifth star nobody earned. */
.stars.part{position:relative;display:inline-block;line-height:0}
.stars.part .row{display:inline-flex;gap:3px}
.stars.part .row.lit{
  position:absolute;top:0;left:0;width:var(--fill,100%);overflow:hidden;white-space:nowrap;
}

.says-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:18px}
.says-head .avg{font-family:var(--mono);font-size:15px;color:var(--paper);letter-spacing:-.01em}
.says-head .how{font-size:14px;color:var(--paper-3)}

/* The reel around them is not the one around a screenshot: no plate behind it,
   and every slide holds the same cell so the box is the height of the tallest
   and does not jump as it turns. */
.says-reel{background:none;box-shadow:none;padding:0}
.says-reel .slides{display:grid}
.says-reel .slide{position:relative;inset:auto;display:block;grid-area:1/1}
.says-reel .slide:not(.on){opacity:0;visibility:hidden;pointer-events:none}
.reel-bar{display:flex;align-items:center;justify-content:center;gap:16px;margin-top:18px}
.says-reel .reel-go{position:static;transform:none;width:34px;height:34px}
.says-reel .dots{margin-top:0}

/* Writing one. Radios drawn as stars, so it works with a keyboard and with no
   script at all, and reads as a rating to anything that cannot see it. */
.rev-write{margin-top:22px}
.field > .lbl{
  font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--paper-3);
}
/* Written backwards, five first, so the ones before the hovered star can be lit
   with a sibling selector and no script. */
.pick-stars{display:flex;flex-direction:row-reverse;justify-content:flex-end;gap:6px}
.pick-stars input{position:absolute;opacity:0;width:1px;height:1px}
.pick-stars label{
  width:26px;height:26px;cursor:pointer;background:var(--paper-3);opacity:.26;
  clip-path:polygon(50% 0,61.8% 34.5%,98% 34.5%,68.2% 57.3%,79.4% 100%,50% 71.5%,20.6% 100%,31.8% 57.3%,2% 34.5%,38.2% 34.5%);
  transition:background .15s ease, opacity .15s ease;
}
.pick-stars label .vis{position:absolute;left:-9999px}
.pick-stars input:checked ~ label,
.pick-stars label:hover,
.pick-stars label:hover ~ label{background:var(--red);opacity:1}
.pick-stars input:focus-visible + label{outline:2px solid var(--red);outline-offset:3px}
.reel .dot:focus-visible{outline:2px solid var(--red);outline-offset:3px}

@media (max-width:640px){
  .reel{padding:10px}
  .reel-go{width:34px;height:34px}
  .reel-go.prev{left:8px}
  .reel-go.next{right:8px}
}

/* Screenshots with words beside them: level tops, level bottoms. */
.shots-row{align-items:center}

/* The row under the cart lines. Keep shopping on its own; the discount field
   and the button that applies it stay together whatever the width. */
.cart-actions{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:22px}
.cart-actions .coupon{display:flex;align-items:center;gap:10px;flex:1 1 320px;min-width:0}
.cart-actions .coupon input{flex:1 1 auto;min-width:0;max-width:260px}
.cart-actions .coupon .btn{flex:0 0 auto}
@media (max-width:560px){
  .cart-actions{gap:12px}
  .cart-actions > .btn{width:100%;justify-content:center}
  .cart-actions .coupon{flex:1 1 100%}
  .cart-actions .coupon input{max-width:none}
}

/* ==========================================================================
   The cart, laid out.
   Two plates that begin and end together, with the small print resting on the
   bottom of the taller one instead of leaving a hole under it.
   ========================================================================== */

.woocommerce-cart .cols.side{align-items:stretch}
/* Both halves the same width. The totals are not a footnote to the basket:
   they are the half somebody actually reads before pressing the button.
   Above the width where the two stop fitting side by side, and no lower: this
   rule is more specific than the one that stacks them, so left unguarded it
   drew two columns a hundred and sixty pixels wide on a phone. */
@media (min-width:901px){
  .woocommerce-cart .cols.side{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
}
.woocommerce-cart .cols.side > div{display:flex;flex-direction:column}
.woocommerce-cart .cols.side > div > .panel{flex:1;display:flex;flex-direction:column}
/* The line about not needing an address sits at the foot of the plate. */
.woocommerce-cart .cart_totals{margin-top:4px}
.woocommerce-cart .panel > .under{margin-top:auto;padding-top:16px}

/* The bar that follows you down a product page. One price, one button, and
   nothing at all until the button at the top has gone. */
.prodbar .bar-buy{display:flex;align-items:center;gap:14px;margin-left:22px;flex:0 0 auto}
.prodbar .bar-buy .price{
  font-family:var(--mono);font-size:14px;font-variant-numeric:tabular-nums;color:var(--paper);
  white-space:nowrap;
}
.prodbar .bar-buy .ctas{margin:0}
.prodbar .bar-buy form.cart{margin:0;padding:0;display:flex}
.woocommerce .prodbar .bar-buy .button{padding:9px 16px;font-size:13.5px;border-radius:7px;white-space:nowrap}
/* On a phone the bar is the only place the price and the button appear
   together, so the price stays and the plugin's name gives way instead: the
   name is at the top of the page in type an inch tall. */
@media (max-width:760px){
  .prodbar .bar-buy{margin-left:auto;gap:10px}
  .prodbar .bar-buy .price{font-size:13px}
}
@media (max-width:430px){
  .prodbar .nm{display:none}
  /* The name goes and the platform stays. The name is at the top of the page
     in type an inch tall; the platform is written nowhere else on this screen
     once the hero has scrolled away. */
  .prodbar .runs-tag{font-size:9.5px;letter-spacing:.1em;padding:4px 7px}
}
/* The trial and the Add to cart button sit side by side, never one stacked on
   the other. On a wide screen they keep their natural size in the bar; on a
   tablet or a phone, where the single row would run off the edge, the buy area
   drops to its own full-width row and the two buttons share it as equal halves
   so neither is squeezed to nothing and nothing overflows the screen. */
.prodbar .bar-buy .ctas{flex-wrap:nowrap;gap:10px}
.prodbar .bar-buy .ctas > a.btn,
.prodbar .bar-buy .ctas > form.cart{margin-left:0}
.prodbar .bar-buy .ctas form.cart{flex:0 0 auto;display:flex}
.woocommerce .prodbar .bar-buy .ctas form.cart .button{width:100%}
.prodbar .bar-buy .ctas > a.btn{white-space:nowrap;justify-content:center}
@media (max-width:900px){
  .prodbar .plate{flex-wrap:wrap;height:auto;padding-block:8px;gap:8px 14px}
  .prodbar .bar-buy{flex:1 1 100%;min-width:0;margin-left:0;margin-top:2px}
  .prodbar .bar-buy .ctas{flex:1 1 auto;min-width:0;display:grid;grid-template-columns:1fr 1fr}
  .prodbar .bar-buy .ctas > a.btn,
  .prodbar .bar-buy .ctas > form.cart{min-width:0}
  .prodbar .jump{margin-left:0}
}

/* The panel's own sign-in, wherever it is drawn. Narrow, because a form with
   two fields in it has no business being the width of a page. */
.ptf-signin{max-width:32rem}
.ptf-signin .form{display:grid;gap:16px;margin-top:16px}
.ptf-signin .actions{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.login .ptf-signin{max-width:none;background:none;box-shadow:none;padding:0}

/* ==========================================================================
   The menu on a phone.
   The links were a row that scrolled sideways with its scrollbar hidden, which
   meant half of them were off the right edge of the screen and nothing on the
   page said so. Now: the wordmark, the cart, and a button that says Menu.
   ========================================================================== */

.menu-toggle{
  display:none;margin-left:14px;flex:0 0 auto;
  width:40px;height:40px;padding:0;border-radius:8px;cursor:pointer;
  background:none;border:1px solid var(--edge-hi);
  align-items:center;justify-content:center;
  transition:border-color .18s ease, background .18s ease;
}
.menu-toggle:hover{border-color:var(--paper-3)}
.menu-toggle:focus-visible{outline:2px solid var(--red);outline-offset:2px}

/* Three lines that become a cross when it is open. */
.menu-toggle .bars,
.menu-toggle .bars::before,
.menu-toggle .bars::after{
  display:block;width:17px;height:1.5px;background:var(--paper);border-radius:2px;
  transition:transform .25s ease, opacity .2s ease;
}
.menu-toggle .bars{position:relative}
.menu-toggle .bars::before,
.menu-toggle .bars::after{content:"";position:absolute;left:0}
.menu-toggle .bars::before{top:-6px}
.menu-toggle .bars::after{top:6px}
.site-head.open .menu-toggle .bars{background:transparent}
.site-head.open .menu-toggle .bars::before{transform:translateY(6px) rotate(45deg)}
.site-head.open .menu-toggle .bars::after{transform:translateY(-6px) rotate(-45deg)}

.site-head .cart{margin-left:auto}
.site-head .nav ~ .cart{margin-left:0}

@media (max-width:820px){
  .site-head .plate{gap:12px}

  .menu-toggle{display:inline-flex}

  /* The sheet. Under the bar, the full width of the screen, one link a line. */
  .nav{
    position:absolute;left:0;right:0;top:100%;margin:0;z-index:5;
    display:grid;gap:0;
    /* Opaque, and lit from the top edge like every other plate. The bar itself
       is translucent; a sheet hanging off it must not be, or the page shows
       through the links. */
    background-image:var(--face);
    background-color:var(--ink-850);
    box-shadow:0 26px 44px -26px #000, inset 0 1px 0 var(--edge-hi), inset 0 -1px 0 var(--rule);
    max-height:0;overflow:hidden;visibility:hidden;
    transition:max-height .28s ease, visibility .28s;
  }
  .site-head.open .nav{max-height:70vh;overflow-y:auto;visibility:visible}

  .nav a{
    padding:16px clamp(16px,5vw,28px);font-size:16px;color:var(--paper);
    border-bottom:1px solid var(--rule);
  }
  .nav a:last-child{border-bottom:0}
  .nav a.panel-link{color:var(--red)}

  .site-head .cart{margin-left:auto;font-size:13px}
}

/* No sheet at all on a wide screen, whatever the button was left doing. */
@media (min-width:821px){
  .site-head.open .nav{max-height:none;visibility:visible;overflow:visible}
}

/* ==========================================================================
   Light theme -- the American-flag palette, opt-in.

   The dark theme is the bare :root above and does not change. This block only
   redefines the colour tokens when the header switch has put data-theme="light"
   on the page: a white ground, black text, flag-blue titles and flag-red
   buttons. Nothing here touches a component rule, only the values it reads.
   ========================================================================== */
:root[data-theme="light"]{
  --ink-900:#ffffff;
  --ink-850:#ffffff;
  --ink-800:#f6f7f9;                   /* a card face, a hair off white so it reads */
  --ink-700:#eceef2;
  --edge:rgba(23,27,56,.10);           /* edges become dark-on-light */
  --edge-hi:rgba(23,27,56,.17);
  --rule:rgba(23,27,56,.13);
  --grime:none;                        /* no warm dirt on a clean white plate */
  --face:linear-gradient(176deg,#ffffff 0%,#fbfbfd 58%,#f6f7f9 100%);
  --face-hi:linear-gradient(176deg,#ffffff 0%,#f2f4fa 100%);
  --paper:#111319;                     /* black text */
  --paper-2:#3d4048;
  --paper-3:#6a6d75;
  --red:#B22234;                       /* Old Glory Red */
  --red-hot:#c62a3c;
  --red-dim:rgba(178,34,52,.5);
  --fault:#c62a3c;
  --title:#2F4FCC;                     /* a brighter flag blue, lifted off the navy so it reads as American blue on white */
  /* The drop shadow under a plate reads much heavier on white than on black,
     so it is eased back by about a third here. Only the black shadow layer
     changes; the inset highlight is invisible on white anyway. */
  --lift:0 1px 0 rgba(237,232,224,.06) inset, 0 24px 48px -32px rgba(0,0,0,.58);
  --lift-hi:0 1px 0 rgba(237,232,224,.11) inset, 0 34px 60px -30px rgba(0,0,0,.66);
}
/* The two bars whose ground was a hardcoded near-black, so the blur sits on
   white instead. */
:root[data-theme="light"] .site-head{background:rgba(255,255,255,.72)}
:root[data-theme="light"] .prodbar{background:rgba(255,255,255,.85)}
:root[data-theme="light"] ::selection{background:var(--red);color:#fff}
/* The "Try free" outline keeps the plain dark frame it has always had (firmed
   up a touch for white), with black text; on hover the frame -- and only the
   frame -- lights flag blue. The red Add to cart is left completely alone, red
   fill and its own brighten-and-lift on hover, no blue anywhere near it. The
   section rule stays its original red. */
:root[data-theme="light"] .btn.ghost{border-color:rgba(23,27,56,.32)}
:root[data-theme="light"] .btn.ghost:hover{border-color:var(--title);box-shadow:0 0 0 1px var(--title);background:none;transform:none}
/* The price goes flag red in light mode -- red digits, blue titles, black text. */
:root[data-theme="light"] .obj .price,
:root[data-theme="light"] .buy .price,
:root[data-theme="light"] .prodbar .bar-buy .price,
:root[data-theme="light"] .woocommerce div.product p.price,
:root[data-theme="light"] .woocommerce div.product span.price,
:root[data-theme="light"] .woocommerce ul.products li.product .price{
  color:var(--red);
}

/* ---- the light / dark switch, in the header beside the cart -------------- */
.theme-toggle{
  position:relative;flex:0 0 auto;display:inline-block;box-sizing:border-box;
  width:56px;height:28px;padding:0;border-radius:999px;cursor:pointer;
  border:1px solid var(--edge-hi);background:var(--ink-800);transition:border-color .2s ease;
  -webkit-tap-highlight-color:transparent;
}
.theme-toggle:hover{border-color:var(--paper-3)}
/* The two icons sit at fixed centres, one 14px in from each end, and the knob
   rests on exactly those same centres -- so whichever icon is lit is dead
   centre in the circle, in both positions. */
.theme-toggle svg{
  position:absolute;top:50%;transform:translateY(-50%);width:14px;height:14px;
  z-index:2;color:var(--paper-3);transition:color .2s ease;
}
.theme-toggle .tt-moon{left:6px}
.theme-toggle .tt-sun{right:6px}
/* The crescent is drawn ~2.4 units right of its own box centre (a moon is not
   symmetric in its box the way the sun is), so it is nudged left to land dead
   centre in the knob. Measured, not guessed: 2.42 * 14/24 ≈ 1.4px. */
.theme-toggle .tt-moon{transform:translateY(-50%) translateX(-1.4px)}
.theme-toggle .tt-knob{
  position:absolute;top:50%;left:2px;width:22px;height:22px;border-radius:50%;
  background:var(--red);z-index:1;transform:translateY(-50%);
  transition:transform .22s ease;box-shadow:0 2px 8px -3px rgba(0,0,0,.55);
}
/* Dark is the default: the knob rests over the moon, and the moon is the lit one. */
:root:not([data-theme="light"]) .theme-toggle .tt-moon{color:#fff}
/* Light: the knob slides to the sun's centre (28px = the gap between the two centres). */
:root[data-theme="light"] .theme-toggle .tt-knob{transform:translateY(-50%) translateX(28px)}
:root[data-theme="light"] .theme-toggle .tt-sun{color:#fff}

/* ---- intro price: the regular struck under "Regular", the intro under "2 weeks
   Intro Price" ------------------------------------------------------------- */
/* The intro price carries no underline. The regular price is muted and crossed
   by a red slash drawn on the diagonal, rather than the browser's flat
   line-through, so the discount reads at a glance in either theme. */
.price ins{text-decoration:none}
.price del{position:relative;text-decoration:none;color:var(--paper-3);opacity:1}
.price del::after{
  content:"";position:absolute;left:-5%;right:-5%;top:50%;height:2px;border-radius:2px;
  background:var(--red);transform:translateY(-50%) rotate(-8deg);
}
/* The two labelled figures, side by side on the wide displays. A small line over
   each figure names it; the figures sit on one baseline so the labels do not
   push them out of line. */
.price .ptf-sale{display:inline-flex;align-items:flex-end;gap:20px}
/* The label sits tight on top of its figure and left-aligned to it, so it reads
   as a caption on the price rather than a separate line. */
.price .ptf-sale .pp{display:inline-flex;flex-direction:column;align-items:flex-start;gap:1px}
.price .ptf-sale del,.price .ptf-sale ins{font-size:inherit;line-height:1.05}
.price .ptf-sale .lab{
  font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--paper-3);white-space:nowrap;line-height:1;
}
/* On the small three-across cards the pair stacks, regular over the intro; the
   wide newest-release box keeps them side by side. */
.obj:not(.hero-obj) .foot .price .ptf-sale{flex-direction:column;align-items:flex-start;gap:10px}

/* ------------------------------------------------------------ mail: the dashboard's mail screens
   The editor is the boxes on the left and the mail itself on the right, redrawn as it is
   written. The picture is an iframe with the mail's own HTML in it; a new one loads behind
   the old and is swapped in, so it never flashes blank. */
.mail-editor{display:grid;grid-template-columns:minmax(0,1fr) 440px;gap:22px;align-items:start}
@media (max-width:1120px){.mail-editor{grid-template-columns:1fr}}
.mail-left{min-width:0}
.mail-preview{position:sticky;top:16px}
.mail-preview .panel{margin-bottom:18px}
.mlsubject{margin:0 0 12px;font-size:15px}
.mlframe{position:relative;min-height:420px;background:#0B0B0D;border:1px solid var(--rule);overflow:hidden}
.mlframe iframe{display:block;width:100%;height:760px;border:0}
.mlframe iframe+iframe{position:absolute;inset:0;opacity:0}
[data-mlpreview].updating .mlframe{opacity:.7;transition:opacity .2s}
.mail-form .panel.step{margin-bottom:18px}
.step .lab i{display:inline-block;min-width:22px;height:22px;line-height:22px;margin-right:10px;border-radius:50%;background:var(--red);color:#fff;text-align:center;font-style:normal;font-size:11px}
.mail-send .panel.step{margin-bottom:18px}
.kinds{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
@media (max-width:1000px){.kinds{grid-template-columns:repeat(2,1fr)}}
@media (max-width:560px){.kinds{grid-template-columns:1fr}}
.kind{display:flex;flex-direction:column;gap:10px;padding:20px;background:var(--face);border:1px solid var(--edge);box-shadow:var(--lift)}
.kind h3{margin:0;font-size:17px}
.kind p{flex:1;margin:0;font-size:13.5px}
.kindpick{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px}
.pillpick{position:relative}
.pillpick input{position:absolute;opacity:0;width:0;height:0}
.pillpick span{display:inline-block;padding:7px 12px;border:1px solid var(--edge-hi);border-radius:2px;font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--paper-3);cursor:pointer}
.pillpick input:checked+span{border-color:var(--red);color:var(--red)}
.pillpick input:focus-visible+span{outline:2px solid var(--red-hot);outline-offset:2px}
.mpicks{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:4px 0 8px}
@media (max-width:700px){.mpicks{grid-template-columns:repeat(2,1fr)}}
.mpick{display:block;position:relative;border:1px solid var(--edge);background:var(--face-hi);cursor:pointer}
.mpick input{position:absolute;top:8px;left:8px;margin:0}
.mpick img,.mpick .noimg{display:block;width:100%;aspect-ratio:1;object-fit:cover;background:#0B0B0D}
.mpick span{display:block;padding:8px 10px 10px}
.mpick b{display:block;font-size:13px;line-height:1.25}
.mpick em{display:block;font-style:normal;font-family:var(--mono);font-size:11.5px;color:var(--paper-3);margin-top:3px}
.mpick.on{border-color:var(--red)}
.mpick.off{opacity:.45;cursor:default}
.meter{display:block;height:6px;margin-top:6px;max-width:120px;background:var(--rule);border-radius:3px;overflow:hidden}
.meter.big{max-width:none;height:8px;margin:0 0 12px}
.meter i{display:block;height:100%;background:var(--red)}
.mllint td:first-child{width:1%;white-space:nowrap}
.panel.zine{border-left:3px solid var(--red)}
.msec{border:1px solid var(--edge);padding:12px 14px;margin:0 0 12px;background:var(--face-hi)}
.hint.red{color:var(--red-hot)}
.tbl .nowrap,.tbl .pill{white-space:nowrap}
.tbl.refusals th{white-space:nowrap}
.tbl.refusals td.why{min-width:320px}
.ptf-gift{margin:0 0 18px}
.ptf-gift-form{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.ptf-gift-form input[type=text]{min-width:220px;font-family:var(--mono);text-transform:uppercase}
.msec.off{opacity:.55}
.msec img{display:block;max-width:220px;height:auto;margin:6px 0 10px;border:1px solid var(--edge)}
/* the preview's size: a phone, the mail's own 600px, or wide; short or tall */
.mlsize{margin:0 0 10px}
.mail-editor.size-phone{grid-template-columns:minmax(0,1fr) 420px}
.mail-editor.size-phone .mlframe{width:375px;margin:0 auto}
.mail-editor.size-mail{grid-template-columns:minmax(0,1fr) 640px}
.mail-editor.size-wide{grid-template-columns:minmax(0,2fr) minmax(0,3fr)}
.mail-editor.height-tall .mlframe iframe{height:1400px}
@media (max-width:1120px){.mail-editor.size-phone,.mail-editor.size-mail,.mail-editor.size-wide{grid-template-columns:1fr}}
[data-notefor] textarea{min-height:72px}
.note.ok{border-color:var(--paper-3)}
.finder{display:flex;gap:10px;align-items:center;margin:0 0 14px}
.finder input[type=search]{flex:1;min-width:0}
.inline{display:inline-flex;gap:6px}
details.fold summary{cursor:pointer;list-style:none}
details.fold summary::-webkit-details-marker{display:none}
details.fold[open] summary{margin-bottom:12px}
.ptf-join{display:grid;gap:10px;max-width:420px}
.ptf-join label span{display:block;font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--paper-3);margin-bottom:6px}
.ptf-join input[type=email]{width:100%}
.ptf-join-note,.ptf-join-said{font-size:13px;color:var(--paper-3);margin:0}

/* Classes the mails and the leave page use inside their own <style>: listed so the audit
   knows they are meant. They are styled in the mail, never from here. */
.pad,.col,.h1,.wrap,.card,.rule,.foot{}
