/* workspace/starcode/css/cosmos-license.css -- the Surveyor's License card
   (js/license-card.js). Same physical-paper family as the passport book
   (css/cosmos-passport.css): the card is a fixed aged-paper document,
   deliberately theme-invariant -- a physical document keeps its own ink
   regardless of the app's light or dark theme setting, so these custom
   properties are declared once here, never split into light/dark variants.
   --card-ink/--card-dim/--card-accent/--card-line/--card-hair are copied
   verbatim from the passport's own default motif (js/passport-motifs.js
   Motif B, "Aged paper") so the two documents read as one set, not two
   separate looks. --card-label and --card-accent-text are new, local to
   this card: --card-dim and --card-accent measured under 1.7:1 and 3.4:1
   against this paper's own gradient (checked against all three of its
   color stops) -- unreadable for small label text and the class chip,
   nowhere near the 4.5:1 that real words need. --card-label and
   --card-accent-text are darker shades of the same two colors, each
   checked to clear 4.5:1 against every stop of the paper gradient, and are
   what all real text on the card reads from now; --card-dim stays for the
   barcode graphic alone, which is not text. Every font comes from the
   app's own stacks -- headings use --font-body, numeric/label text uses
   --font-data (a monospace stack), both defined by css/cosmos-base.css --
   and nothing loads from the network. Landscape, credit-card proportioned
   (owner order 2026-08-22): width fills the mount up to a fixed cap, height
   follows from a fixed aspect ratio, so a phone still gets a wide card, not
   a tall one. */
.license-card-mount { position: relative; width: 100%; max-width: 560px;
  --card-ink: #3a2c14; --card-dim: #8a7550; --card-accent: #7a3420;
  --card-label: #42321b; --card-accent-text: #5a2416;
  --card-line: rgba(122, 52, 32, .45); --card-hair: rgba(40, 25, 5, .18); }
.license-card { position: relative; width: 100%; aspect-ratio: 8 / 5; perspective: 1600px; transition: transform .3s ease; }
/* The 3D flip (owner order 2026-08-22): a control on either face turns the
   card over in ~0.5s. .card-flip carries the 180deg turn; each .card-face
   is one full side, hidden from view whichever way it is facing away from
   the screen (backface-visibility), so only one face is ever readable at a
   time -- the other one is there, just turned around. */
.card-flip { position: absolute; inset: 0; transform-style: preserve-3d; transition: transform .5s cubic-bezier(.4, .1, .2, 1); }
.card-flip.is-flipped { transform: rotateY(180deg); }
.card-face { position: absolute; inset: 0; border-radius: 10px; overflow: hidden; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  background: linear-gradient(155deg, #d9c79a 0%, #c9b076 60%, #b89c5e 100%);
  border: 1px solid var(--card-line); box-shadow: 0 22px 48px rgba(0, 0, 0, .5); }
.card-face.face-back { transform: rotateY(180deg); }
.card-face::after { content: ""; position: absolute; inset: 0;
  background: linear-gradient(var(--sheen-angle, 105deg), transparent 42%, rgba(255, 255, 255, .16) 50%, transparent 58%); pointer-events: none; z-index: 2; }
.card-face::before { content: ""; position: absolute; inset: 0; border-radius: 10px; box-shadow: 0 0 0 1px rgba(255, 255, 255, .08) inset; pointer-events: none; z-index: 2; }
.card-face .watermark-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; }
.card-face .card-inner { position: relative; z-index: 1; height: 100%; box-sizing: border-box; padding: 14px 18px 12px; display: flex; flex-direction: column; gap: 8px; }
.license-card .card-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
/* min-width: 0 lets this column actually shrink below its text's natural
   width -- a plain flex child refuses to by default, which is what let a
   narrow phone card's authority/title text wrap to two lines each and
   balloon the header tall enough to starve the body below it (owner
   feedback 2026-08-23, third round: verified live at 375px). One line with
   an ellipsis at the extreme is the trade, never a header that eats the
   card. */
.license-card .card-header > div:first-child { flex: 1 1 auto; min-width: 0; }
.license-card .card-authority { margin: 0; font-size: 9px; letter-spacing: 1.6px; text-transform: uppercase; color: var(--card-label); font-family: var(--font-data); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.license-card .card-title { margin: 0; font-family: var(--font-body); font-weight: 700; font-size: 20px; letter-spacing: .5px; color: var(--card-ink); line-height: 1.05; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.license-card .card-classbadge { flex: 0 0 auto; border: 1px solid var(--card-line); border-radius: 6px; padding: 4px 7px; font-family: var(--font-data); font-size: 11px; letter-spacing: 1px; color: var(--card-accent-text); text-align: center; line-height: 1.2; white-space: nowrap; }
.license-card .card-classbadge small { display: block; color: var(--card-label); font-size: 8px; letter-spacing: .6px; margin-top: 1px; text-transform: none; white-space: normal; max-width: 96px; }
/* The back face's own small verify chip (front's verify moved to the
   full-width footer band below, owner feedback 2026-08-23). */
.license-card .card-verify-mini { display: flex; flex-direction: column; align-items: center; gap: 1px; }
.license-card .card-verify-mini canvas { width: 60px; height: 10px; display: block; }
.license-card .card-hash { margin: 0; font-family: var(--font-data); font-size: 8px; letter-spacing: 1px; color: var(--card-label); white-space: nowrap; }
.license-card .card-verify-mini .card-hash { font-size: 6px; }
/* The landscape body: a photo column on the left, the data stack on the
   right (owner order 2026-08-22, "photo left column, data right" -- the
   reference cards' own layout). The photo column is a third of the card's
   own width now (owner feedback 2026-08-23, third round: the old fixed
   96px column read thin against the reference ID-card photos). */
.license-card .card-body { flex: 1; min-height: 0; display: flex; gap: 12px; }
.license-card .card-portrait { flex: 0 0 32%; max-width: 150px; align-self: stretch; padding: 0; border: 1px solid var(--card-line); border-radius: 6px; background: #0c0f16; cursor: pointer; position: relative; overflow: hidden; transition: transform .1s ease; }
.license-card .card-portrait:active { transform: scale(.97); }
/* js/license-card.js sizes this canvas off the frame's own measured box
   every render (drawPortraitToFrame), so its intrinsic aspect always
   equals the frame's real aspect -- object-fit: contain is a pure safety
   net against sub-pixel rounding, never an active crop or stretch. */
.license-card .card-portrait canvas { width: 100%; height: 100%; display: block; object-fit: contain; object-position: center; }
/* The three form sections spread across the column's full height, so the
   spare room at a wide render pools BETWEEN sections as breathing space --
   never as one blank band above the footer. */
.license-card .card-data { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; justify-content: space-between; }
.license-card .identity-field { display: flex; flex-direction: column; gap: 1px; }
/* A hairline between the surveyor block and the vessel block, matching the
   one card-fields already carries above the dates -- three dense stacked
   sections read as one official form, not two blocks with a bare middle. */
.license-card .vessel-field { border-top: 1px solid var(--card-hair); padding-top: 4px; margin-top: 2px; }
.license-card .vessel-row { display: flex; align-items: center; gap: 8px; }
.license-card .vessel-row .card-name { flex: 1; min-width: 0; }
.license-card .ship-thumb { flex: 0 0 56px; width: 56px; height: 42px; padding: 0; border: 1px solid var(--card-line); border-radius: 5px; background: #0a0d13; cursor: pointer; overflow: hidden; }
.license-card .ship-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.license-card .ship-thumb svg { width: 60%; height: 60%; margin: 20%; color: var(--card-dim); display: block; }
/* The card-portrait/ship-thumb backing (above) stays a fixed dark photo
   bezel -- it sits behind an opaque canvas or image almost always, so it is
   kept literal rather than reading the paper card's own light ink tokens. */
.license-card .cell-hint { position: absolute; left: 0; right: 0; bottom: 0; background: rgba(5, 7, 13, .72); color: #f5a623; font-family: var(--font-data); font-size: 9px; letter-spacing: 1.2px; text-align: center; padding: 3px 0; opacity: 0; transition: opacity .15s ease; }
.license-card .card-portrait:hover .cell-hint, .license-card .card-portrait:focus-visible .cell-hint { opacity: 1; }
.license-card .card-namelabel { margin: 0; font-size: 8px; letter-spacing: 1.6px; text-transform: uppercase; color: var(--card-label); font-family: var(--font-data); }
.license-card .card-name { margin: 1px 0 2px; font-family: var(--font-body); font-weight: 600; font-size: 17px; color: var(--card-ink); line-height: 1.1; word-break: break-word; }
.license-card .card-licenseno { margin: 0; font-family: var(--font-data); font-size: 11px; letter-spacing: .8px; color: var(--card-label); }
.license-card .card-licenseno span { color: var(--card-ink); }
.license-card .card-fields { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px 10px; padding: 6px 0 0; border-top: 1px solid var(--card-hair); }
.license-card .field-label { margin: 0 0 2px; font-size: 8px; letter-spacing: 1.2px; text-transform: uppercase; color: var(--card-label); font-family: var(--font-data); }
.license-card .field-value { margin: 0; font-family: var(--font-data); font-size: 11px; letter-spacing: .3px; color: var(--card-ink); font-variant-numeric: tabular-nums; }
/* The verify barcode as a real full-width strip along the bottom edge
   (owner feedback 2026-08-23, third round: the reference ID-card photos
   all anchor the barcode down here, not as a thumbnail in a header
   corner) -- padding-right clears the flip button, which sits absolute
   over this same corner on both faces. js/license-card.js measures this
   canvas's own rendered box and draws it crisp at that size. */
.license-card .card-footer { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; padding: 6px 76px 0 0; border-top: 1px solid var(--card-hair); }
.license-card .card-barcode-strip { flex: 1; min-width: 0; height: 20px; display: block; }
/* The flip control: a small pill on both faces, top of the paper but its
   own frosted chip so it stays readable over either the photo column or
   the seal grid it sits near. */
.license-card .flip-btn { position: absolute; right: 8px; bottom: 8px; z-index: 3; min-height: 28px; font-family: var(--font-data); font-size: 9px; letter-spacing: 1px; text-transform: uppercase; color: var(--card-accent-text); background: rgba(255, 255, 255, .4); border: 1px solid var(--card-line); border-radius: 14px; padding: 4px 10px; cursor: pointer; }
.license-card .flip-btn:hover { background: rgba(255, 255, 255, .6); }
/* The back face: a body row holding the achievement seals beside the QR
   label. The seals keep their plain grid (owner order 2026-08-22) and take
   the row's remaining width; the label column is fixed-proportion so the
   code stays big enough to scan. */
.license-card .card-backbody { flex: 1; min-height: 0; display: flex; gap: 10px; align-items: center; }
.license-card .card-seals { flex: 1; min-height: 0; display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(2, 1fr); gap: 4px; align-items: center; justify-items: center; padding-top: 2px; }
/* The QR label (SC-QR-DOCS): a printed light patch carrying the baked
   module matrix for the plain public game URL, with the URL itself as a
   one-line caption underneath. Scannability beats aesthetics here: the
   patch is the lightest surface on the card and the modules are near-black
   (js/qr-link-draw.js paints both, plus the standard quiet zone), so a
   phone reads it off this screen. The canvas is square by aspect-ratio and
   the painter measures its real box, same discipline as every other canvas
   on the card. */
.license-card .card-qrlabel { flex: 0 0 auto; width: 31%; max-width: 118px; box-sizing: border-box; background: #f8f1de; border: 1px solid var(--card-hair); border-radius: 4px; padding: 4px 4px 2px; display: flex; flex-direction: column; align-items: center; gap: 1px; box-shadow: 0 1px 3px rgba(40, 25, 5, .25); }
.license-card .card-qrcanvas { width: 100%; aspect-ratio: 1; display: block; }
.license-card .card-qrcaption { margin: 0; max-width: 100%; overflow: hidden; font-family: var(--font-data); font-size: 6px; letter-spacing: .3px; color: var(--card-label); white-space: nowrap; }
.license-card .stamp { position: relative; width: 100%; max-width: 72px; aspect-ratio: 1; cursor: pointer; background: transparent; border: 0; padding: 0; }
.license-card .stamp canvas { width: 100%; height: 100%; display: block; }
.license-card .stamp-label { position: absolute; bottom: 10%; left: 0; right: 0; text-align: center; font-family: var(--font-data); font-size: 6px; letter-spacing: .4px; color: var(--card-accent-text); pointer-events: none; text-transform: uppercase; }
/* The holographic sheen (owner order 2026-08-22): earned seals only, an
   iridescent gradient ring layered with color-dodge so it reads as a light
   foil catch, not a solid color -- tasteful over the paper texture, never
   covering the ink stamp itself. Unearned seals keep the plain quiet ink
   outline the canvas already draws, no extra treatment. */
.license-card .stamp.is-unlocked::after { content: ""; position: absolute; inset: 8%; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from 0deg, rgba(255, 166, 214, .4), rgba(140, 220, 255, .4), rgba(201, 166, 255, .4), rgba(255, 229, 140, .4), rgba(255, 166, 214, .4));
  mix-blend-mode: color-dodge; opacity: .5; animation: seal-holo-spin 7s linear infinite; }
@keyframes seal-holo-spin { to { transform: rotate(360deg); } }
.license-card .stamp-caption { margin: 0; min-height: 11px; font-family: var(--font-data); font-size: 9px; color: var(--card-label); text-align: center; }
/* The portrait-customize popup is a floating control panel, not part of
   the paper document itself -- it keeps its own original dark-UI colors
   (the card's exact old palette, before this file's paper repaint) rather
   than reading the paper tokens, which now mean "dark ink on light paper"
   and would be unreadable on this popup's dark body. */
.license-card-mount .popup-backdrop { position: fixed; inset: 0; background: rgba(5, 7, 13, .72); display: flex; align-items: center; justify-content: center; padding: 20px; z-index: 10; opacity: 0; pointer-events: none; transition: opacity .15s ease; }
.license-card-mount .popup-backdrop.is-open { opacity: 1; pointer-events: auto; }
.license-card-mount .popup { width: 100%; max-width: 320px; background: linear-gradient(160deg, #171b26, #12141c); border: 1px solid rgba(245, 166, 35, .42); border-radius: 14px; padding: 18px; box-shadow: 0 20px 44px rgba(0, 0, 0, .55); display: flex; flex-direction: column; gap: 10px; }
.license-card-mount .popup-title { margin: 0; font-family: var(--font-body); font-weight: 600; font-size: 17px; color: #d9e0ea; }
.license-card-mount .popup-preview { width: 96px; height: 100px; align-self: center; border: 1px solid rgba(245, 166, 35, .42); border-radius: 6px; background: #0c0f16; }
.license-card-mount .popup-grouplabel { margin: 4px 0 0; font-size: 9px; letter-spacing: 1.4px; text-transform: uppercase; color: #8892a6; font-family: var(--font-data); }
.license-card-mount .popup-row { display: flex; gap: 8px; flex-wrap: wrap; }
.license-card-mount .style-swatch { font-family: var(--font-data); font-size: 10px; color: #8892a6; background: #0c0f16; border: 1px solid rgba(255, 255, 255, .07); border-radius: 6px; padding: 6px 8px; cursor: pointer; }
.license-card-mount .style-swatch.is-selected { color: #f5a623; border-color: rgba(245, 166, 35, .42); }
.license-card-mount .accent-swatch { width: 26px; height: 26px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, .07); cursor: pointer; padding: 0; }
.license-card-mount .accent-swatch.is-selected { border-color: #d9e0ea; }
.license-card-mount .popup-visor { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #8892a6; font-family: var(--font-data); }
.license-card-mount .popup-actions { display: flex; gap: 10px; margin-top: 4px; }
.license-card-mount .popup-apply { flex: 1; font-family: var(--font-data); font-size: 12px; letter-spacing: .6px; text-transform: uppercase; color: #05070d; background: #f5a623; border: 0; border-radius: 7px; padding: 10px 0; cursor: pointer; font-weight: 600; }
.license-card-mount .popup-close { flex: 0 0 auto; font-family: var(--font-data); font-size: 12px; letter-spacing: .6px; text-transform: uppercase; color: #8892a6; background: transparent; border: 1px solid rgba(255, 255, 255, .07); border-radius: 7px; padding: 10px 14px; cursor: pointer; }
@media (prefers-reduced-motion: reduce) {
  .license-card { transition: none; }
  .card-flip { transition: none; }
  .license-card .card-portrait { transition: none; }
  .license-card .stamp.is-unlocked::after { animation: none; }
  .license-card-mount .popup-backdrop { transition: none; }
}
/* Phone compaction (SC-FB11): at narrow widths the fixed-size type no
   longer fits the 8/5 card, so the whole form scales down and the card
   grows a little taller -- every field stays visible, nothing clips, and
   the passport's own narrow-width pass already set this precedent. */
@media (max-width: 460px) {
  .license-card { aspect-ratio: 4 / 3; }
  .card-face .card-inner { padding: 10px 12px 9px; gap: 5px; }
  .license-card .card-title { font-size: 15px; }
  .license-card .card-authority { font-size: 8px; letter-spacing: 1.1px; }
  .license-card .card-classbadge { font-size: 9px; padding: 3px 5px; }
  .license-card .card-body { gap: 8px; }
  .license-card .card-portrait { flex-basis: 30%; max-width: 104px; }
  .license-card .card-name { font-size: 13px; }
  .license-card .card-licenseno { font-size: 9px; }
  .license-card .field-label { font-size: 7px; letter-spacing: .8px; }
  .license-card .field-value { font-size: 9px; }
  .license-card .card-fields { gap: 4px 6px; padding-top: 4px; }
  .license-card .ship-thumb { flex-basis: 44px; width: 44px; height: 34px; }
}
