/* Palette for every page, plus the member card that /reserve still shows on
   its done step. The landing pages moved to the pearl (assets/orb.css); the
   card lives on here because the confirmation screen and its share image are
   still drawn as a card. */
:root {
  --ink: #0b0b0c; --ink-raised: #161617; --bone: #f4f1ea;
  --bone-dim: #a8a49c; --bone-faint: #6f6c66;
  --accent: #d9b36a; --negative: #e64a3c; --positive: #4caf7d;
  --hairline: rgba(244,241,234,.12);
}

/* Two nested wrappers: one element can't run a bob and a spin on `transform`
   without them fighting. .float owns the drift, .card owns the rotation. */
.scene { perspective: 1600px; width: 100%; }
.float { animation: bob 7s ease-in-out infinite; }

/* Still and square by default. Before you've claimed anything the card's job
   is to show YOUR name — turning it away mid-read is the one thing it must
   not do, and a tilt makes the handle harder to read for no gain. Rotation
   is earned. */
.card {
  position: relative; width: 100%; aspect-ratio: 1.586;
  transform-style: preserve-3d;
  transition: transform .3s cubic-bezier(.2,.8,.2,1);
}
/* The cloudflare.pay hover: the card leans a few degrees toward the
   pointer — the corner under the cursor dips, the far corner rises — and
   settles flat when it leaves. The .scene perspective makes the lean read
   as depth. Degrees stay small; it is a lean, not a flip. */
.card { transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) scale(var(--s, 1)); }

/* Phones: NO 3D. A perspective transform makes iOS rasterize the card's
   layer at reduced resolution — that is the blur on the engraving. Touch
   devices get a flat, crisp card with a small press on tap instead. */
@media (hover: none) {
  .scene { perspective: none; }
  .card { transform: none; transform-style: flat; transition: transform .18s ease; }
  /* .pressed is the scripted press: iOS never runs :active on a plain
     div, so the page toggles the class from touch events instead. */
  .card:active, .card.pressed { transform: scale(.965); }
}

/* The plate: one line on a desktop card, two on a phone card. The <br>
   only exists below 460px of card. */
.plate-br { display: none; }
@container (max-width: 460px) {
  .plate-br { display: inline; }
  .card-foot .card-meta { white-space: normal; text-align: right; }
}

.card.turning { animation: spin 26s linear infinite; transform: none; }
.card.turning:hover, .card.turning:active { animation-play-state: paused; }
@keyframes spin { from { transform: rotateY(0deg); } to { transform: rotateY(360deg); } }
@keyframes bob  { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }

.face {
  position: absolute; inset: 0; border-radius: 4.4%/7%; overflow: hidden;
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
  /* The edge has THICKNESS: a milled rim you can see, not a hairline.
     Light strikes from above-left, so the rim is a bright wall along the
     top and left, and a shaded wall along the bottom and right — four
     inset strips, feathered a pixel so they read as machined metal, plus
     a dark outer ring where the side wall turns away from the light. */
  border: 1px solid rgba(70,68,64,.9);
  box-shadow: 0 26px 60px rgba(0,0,0,.6),
              inset 0 2.5px 1px -0.5px rgba(255,255,255,.95),
              inset 2.5px 0 1px -0.5px rgba(255,255,255,.55),
              inset 0 -2.5px 1px -0.5px rgba(42,41,38,.8),
              inset -2.5px 0 1px -0.5px rgba(52,51,48,.6);
  /* Brushed silver: neutral greys with one cool bright band, the way sheet
     metal catches a single light. Neutral so the engraving carries the
     card, and it sits quietly against both the planet and the ink page. */
  background: linear-gradient(128deg,
    #e8e6e1 0%, #b9b7b2 18%, #8e8d89 36%, #d8d6d1 52%,
    #f2f0eb 60%, #a7a5a1 76%, #6f6e6b 92%, #555452 100%);
}
.face.back { transform: rotateY(180deg); display: flex; align-items: center; justify-content: center; }
/* WebKit culls backfaces unreliably on a card whose transform is identity —
   the back's logo bled through the front as a giant ghost. A card that
   isn't spinning has no back worth rendering at all. */
.card:not(.turning) .face.back { display: none; }
.face.back img { width: 34%; opacity: .5;
                 filter: drop-shadow(0 1px 0 rgba(255,255,255,.25)); }
/* Tooth. A polished gradient alone reads as plastic; real stock has
   grain. Fractal noise, desaturated, overlay-blended at low opacity — it
   perturbs the sheen without ever reading as dirt. Sits under ::after so
   the light seam travels OVER the grain, the way light moves on metal. */
.face::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='260'%20height='260'%3E%3Cfilter%20id='n'%3E%3CfeTurbulence%20type='fractalNoise'%20baseFrequency='0.82'%20numOctaves='3'%20stitchTiles='stitch'/%3E%3CfeColorMatrix%20type='saturate'%20values='0'/%3E%3C/filter%3E%3Crect%20width='100%'%20height='100%'%20filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 260px 260px;
  opacity: .35; mix-blend-mode: overlay;
}
.face::after {                     /* travelling light seam */
  content: ""; position: absolute; inset: -30%;
  background: linear-gradient(105deg, transparent 38%, rgba(255,236,230,.4) 48%,
              rgba(244,241,234,.24) 53%, transparent 62%);
  animation: sweep 7s ease-in-out infinite;
}
@keyframes sweep { 0%,100% { transform: translateX(-22%); } 50% { transform: translateX(22%); } }

/* text-align:left matters — these pages are centred, and without it the
   handle and footer centre themselves and stop matching the app. */
.card-inner { position: absolute; inset: 0; padding: 6%; display: flex;
              flex-direction: column; z-index: 1; text-align: left; }

/* Engraving. Everything on a real card is stamped INTO the surface: a dark
   edge where the tool bit, a light edge where the metal catches. One shared
   rule so nothing on the card looks printed on top of it. */
/* Letterpress that scales WITH the type. Pixel offsets were the bug: 1px
   on the 84px handle is a hairline, but on a 10px line it is a fifth of
   the glyph — three visibly separate copies, plus a blur smearing them.
   Em offsets keep the edge proportional at every size, and there is no
   blur layer: engraving is a cut, not a smudge. */
.engraved {
  /* Every engraving on the card is cut from the same stock as the handle:
     the depth is a gradient inside the glyph — dark top wall, lighter
     floor — plus one hairline of light on the bottom lip. Same texture,
     same color, whatever the size. */
  background: linear-gradient(180deg, #34332f 0%, #413f3b 38%, #55534d 72%, #6b6862 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  filter: drop-shadow(0 1px 0 rgba(255,255,255,.4));
}

/* The mark is ~68px and the date is two small lines, so flex-start left
   the date hanging off the top of a tall row and the pair read as ragged.
   They share a centreline instead — the same idea as the foot, where the
   two items share a baseline. */
.card-top { display: flex; align-items: center; justify-content: space-between; flex: 0 0 auto; }
/* Same fill as every engraving, but mono's thin strokes at 9px read
   grayer than the sans line at the foot. Same size as the quote plus a
   weight step makes the two carry the same ink. */
.card-top .card-meta { font-size: clamp(10px, 1.85cqw, 14px); font-weight: 700; }
/* NEVER a percentage height on card art: a % against an indefinite parent
   makes the image contribute its intrinsic height to the flex row and
   crushes everything below it. cq units resolve against a definite width. */

.card-meta { font: 600 clamp(9px, 1.6cqw, 12px)/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
             color: rgba(11,11,12,.6); letter-spacing: 1.9px; text-align: right;
             text-transform: uppercase; }
.card-meta.left { text-align: left; }
.card-foot .card-meta { white-space: nowrap; flex: 0 0 auto; }

/* The real lockup, not a mask of it — masking flattened the wordmark and
   the star into one silhouette and stopped looking like the logo. Engraved
   with the same two edges as the text; the star keeps its own metal
   because it's in the artwork. */
/* Top-left corner now, and much bigger — it's the first thing on the card
   rather than a signature in the corner. */
.card-logo { height: clamp(32px, 9.2cqw, 94px); width: auto; opacity: .82;
             filter: drop-shadow(0 1px 0 rgba(255,255,255,.34))
                     drop-shadow(0 -1px 0 rgba(0,0,0,.26)); }

/* A real cut has NO offset copies — zoom into any engraved card and the
   glyph is one shape, shaded inside: dark at the top wall of the cut,
   lighter where light reaches the floor. So the depth here is a gradient
   CLIPPED TO THE LETTERFORMS, which survives any zoom because there is
   nothing behind the glyph to separate from it. The single hairline of
   light on the bottom lip comes from drop-shadow, which (unlike
   text-shadow) still works when the fill is a clipped gradient. */
.card-handle { font-size: clamp(30px, 11cqw, 84px); font-weight: 650;
               margin: auto 0; letter-spacing: -1.2px; overflow: hidden;
               text-overflow: ellipsis; white-space: nowrap;
               color: rgba(22,22,24,.96);
               background: linear-gradient(180deg,
                 #34332f 0%, #413f3b 38%, #55534d 72%, #6b6862 100%);
               -webkit-background-clip: text; background-clip: text;
               -webkit-text-fill-color: transparent;
               filter: drop-shadow(0 1px 0 rgba(255,255,255,.42));
               text-shadow: none; }
/* `color` fades nothing once the fill is a clipped gradient — the whole
   element steps back instead, cut and all. */
.card-handle.placeholder { opacity: .52; }

/* `flex-end` lines up the BOXES, and the two have different type sizes and
   line-heights, so their baselines landed ~2px apart — enough to see on a
   card this big. `last baseline` lines up the text itself, and the "last"
   matters because the line wraps to two on a phone: it's the bottom line
   that has to sit level with RESERVED, not the first. flex-end stays above
   it as the fallback. */
.card-foot { display: flex; justify-content: space-between;
             align-items: flex-end;
             align-items: last baseline;
             gap: 14px; flex: 0 0 auto; min-height: 0; }
/* Set to exactly the same size as the plate opposite it — same clamp, same
   line-height — so the two ends of the foot read as one row of engraving
   rather than a sentence with a caption stuck next to it. Weight and case
   still differ: this one is meant to be read, RESERVED is meant to be
   glanced at. */
/* Nominally the plate's size, drawn ~15% larger: the plate is uppercase,
   the line is lowercase, and equal point sizes make lowercase LOOK smaller
   — x-height against cap-height. Longhand because `font: ... inherit` is
   an invalid shorthand browsers discard entirely. */
.card-foot .quote { font-weight: 500; letter-spacing: .2px;
                    font-size: clamp(10px, 1.85cqw, 14px);
                    line-height: 1.5; font-family: inherit;
                    color: rgba(11,11,12,.74); max-width: 62%; }
.card-foot .right { text-align: right; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
                    font-size: clamp(9px, 1.55cqw, 12.5px); color: rgba(11,11,12,.55);
                    white-space: nowrap; }

/* Container queries so type scales with the CARD, not the viewport — the
   card is much wider than the page on desktop and vw units broke that. */
.scene { container-type: inline-size; }

/* On a phone-sized card the line drops to the size that fits it on ONE
   line beside the plate — wrapping a nine-word sentence looks like an
   accident at any size. Measured: 10px covers 375px phones and up. */
@container (max-width: 460px) {
  /* A phone-sized card drops the PLATE (open to reserve) — but only the
     plate: the reserve page's MEMBER / NO. corner uses the same class and
     must survive. */
  .card-foot .card-meta.plate { display: none; }
  .card-foot .quote { max-width: none; white-space: nowrap; }
}
/* The old nine-word sentence had to go below 330px; the three-beat line
   fits any card that can carry a name, so it stays at every size. */

/* Decoration, not information — nobody needs it spinning to understand it. */
@media (prefers-reduced-motion: reduce) {
  .float, .card.turning, .face::after { animation: none; }
  .card.turning { transform: none; }
}
