/* fam-ui tokens */

/* Set by the fam-shadow and fam-cast classes and read by the plastic and metal buttons. It must not inherit, or a button inside an elevated
   card would be elevated too. */
@property --fam-elevation {
  syntax: '*';
  inherits: false;
}

:root {
  --fam-tint: #1f7a3d;
  --fam-blue-top: #406eda;
  --fam-blue-mid: #3866d1;
  --fam-blue-bottom: #2f5fc8;
  --fam-glass-blue-shade: rgba(36, 63, 160, .72);
  --fam-cream: #f6ecd2;

  --fam-led: #ff6a1f;

  --fam-font-ui: "Lucida Grande", -apple-system, "Helvetica Neue", sans-serif;
  --fam-font-hand: "Marker Felt", "Bradley Hand", "Segoe Print", cursive;

  /* Controls that can sit on any surface get a two-tone focus ring: this white halo next to the control and a dark outline outside it.
     Whatever the surface, at least one of the two tones reaches 3:1 against it. */
  --fam-focus-halo: 0 0 0 2px #fff;
  --fam-focus-ink: #1b1b20;

  --fam-radius-sm: 6px;
  --fam-radius-md: 12px;
  --fam-radius-lg: 20px;
  --fam-radius-pill: 999px;

  /* The light is straight above, so every shadow falls straight down. Each layer doubles the offset and blur of the one before: dark and crisp
     at the edge, soft and faint farther out, like a real shadow. */
  --fam-shadow-sm: 0 1px 1px rgba(0, 0, 0, .2), 0 2px 3px rgba(0, 0, 0, .12), 0 3px 3px -1px rgba(0, 0, 0, .06);
  --fam-shadow-md: 0 1px 1px rgba(0, 0, 0, .14), 0 2px 2px rgba(0, 0, 0, .1), 0 4px 4px -1px rgba(0, 0, 0, .1), 0 8px 8px -3px rgba(0, 0, 0, .12), 0 12px 12px -5px rgba(0, 0, 0, .1);
  --fam-shadow-lg: 0 1px 1px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .09), 0 4px 4px -1px rgba(0, 0, 0, .09), 0 8px 8px -2px rgba(0, 0, 0, .09), 0 16px 16px -4px rgba(0, 0, 0, .1), 0 28px 28px -8px rgba(0, 0, 0, .12);
  --fam-shadow-inset: inset 0 2px 5px rgba(0, 0, 0, .35), inset 0 -1px 0 rgba(255, 255, 255, .8), 0 1px 0 rgba(255, 255, 255, .8);

  /* Harsher and longer than the elevation shadows, like the knob in the plastic reference: each size is longer and darker than the one before */
  --fam-cast-sm: 0 1px 1px rgba(0, 0, 0, .38), 0 2px 2px rgba(0, 0, 0, .26), 0 4px 4px -1px rgba(0, 0, 0, .22), 0 8px 8px -2px rgba(0, 0, 0, .2), 0 16px 16px -4px rgba(0, 0, 0, .18), 0 30px 28px -8px rgba(0, 0, 0, .16);
  --fam-cast-md: 0 1px 1px rgba(0, 0, 0, .46), 0 2px 2px rgba(0, 0, 0, .31), 0 4px 4px -1px rgba(0, 0, 0, .26), 0 8px 8px -2px rgba(0, 0, 0, .24), 0 16px 16px -4px rgba(0, 0, 0, .22), 0 32px 32px -8px rgba(0, 0, 0, .19), 0 56px 48px -16px rgba(0, 0, 0, .17);
  --fam-cast-lg: 0 1px 1px rgba(0, 0, 0, .55), 0 2px 2px rgba(0, 0, 0, .38), 0 4px 4px -1px rgba(0, 0, 0, .32), 0 8px 8px -2px rgba(0, 0, 0, .29), 0 16px 16px -4px rgba(0, 0, 0, .29), 0 32px 32px -8px rgba(0, 0, 0, .26), 0 60px 52px -14px rgba(0, 0, 0, .26), 0 84px 64px -22px rgba(0, 0, 0, .2);

  --fam-tex-felt-gray-tile: url(../assets/felt-gray-tile.jpg);
  --fam-tex-linen-tile: url(../assets/linen-tile.jpg);
  --fam-tex-denim-tile: url(../assets/denim-tile.jpg);
  --fam-tex-wood-light-tile: url(../assets/wood-light-tile.jpg);
  --fam-tex-wood-paneled-tile: url(../assets/wood-paneled-tile.jpg);
  --fam-tex-metal-tile: url(../assets/metal-tile.jpg);
  --fam-tex-metal-sandblasted: url(../assets/metal-sandblasted-tile.jpg);
  --fam-tex-metal-brushed: url(../assets/metal-brushed.jpg);
  --fam-tex-metal-spiral: url(../assets/metal-spiral.jpg);
  --fam-tex-knob-face: url(../assets/knob-face.jpg);
  --fam-tex-grain-fine: url(../assets/grain-fine.jpg);
  --fam-tex-grain-plastic: url(../assets/grain-plastic.jpg);
  --fam-tex-cardstock-tile: url(../assets/cardstock-tile.jpg);
  --fam-tex-cardboard-tile: url(../assets/cardboard-tile.jpg);
  --fam-tex-legal-tile: url(../assets/legal-tile.jpg);
  --fam-tex-paper-tile: url(../assets/paper-tile.jpg);
  --fam-tex-paper-bag-tile: url(../assets/paper-bag-tile.jpg);
  --fam-tex-lined-paper-tile: url(../assets/lined-paper-tile.jpg);
  --fam-tex-grid-paper-tile: url(../assets/grid-paper-tile.jpg);
  --fam-tex-blackboard-tile: url(../assets/blackboard-tile.jpg);
  --fam-tex-chalkboard-tile: url(../assets/chalkboard-tile.jpg);
  --fam-tex-cork-tile: url(../assets/cork-tile.jpg);
  --fam-tex-leather-tile: url(../assets/leather-tile.jpg);
  --fam-tex-leather-fill-tan-tile: url(../assets/leather-fill-tan-tile.jpg);
  --fam-tex-leather-fill-black-tile: url(../assets/leather-fill-black-tile.jpg);
  --fam-tex-leather-fill-brown-tile: url(../assets/leather-fill-brown-tile.jpg);
  --fam-tex-leather-frame-tan-soft: url(../assets/leather-frame-tan-soft.png);
  --fam-tex-leather-frame-black-soft: url(../assets/leather-frame-black-soft.png);
  --fam-tex-leather-frame-brown-soft: url(../assets/leather-frame-brown-soft.png);
  --fam-tex-leather-bar-edge-tan: url(../assets/leather-bar-edge-tan.png);
  --fam-tex-leather-bar-edge-black: url(../assets/leather-bar-edge-black.png);
  --fam-tex-leather-bar-edge-brown: url(../assets/leather-bar-edge-brown.png);
  --fam-tex-wood-frame: url(../assets/wood-frame.jpg);
  --fam-tex-led-lens-lit: url(../assets/led-lens-lit.png);
  --fam-tex-led-lens-unlit: url(../assets/led-lens-unlit.png);
}

.fam {
  font-family: var(--fam-font-ui);
  font-size: 14px;
  color: var(--fam-cream);
}

/* fam-ui materials */

/* The tile is already grayscale with contrast and brightness baked in, so multiplying it onto the tint recolors the whole texture */
.fam-felt {
  background-color: var(--fam-tint);
  background-image: var(--fam-tex-felt-gray-tile);
  background-size: 256px;
  background-blend-mode: multiply;
}

/* Like the felt, the tile is grayscale and multiplies onto the tint, but it is light (average 215) so a tint stays close to its own color */
.fam-linen {
  background-color: var(--fam-linen-tint, #64656c);
  background-image: var(--fam-tex-linen-tile);
  background-size: 256px;
  background-blend-mode: multiply;
}

/* The twill tile is grayscale with an average of 200, so the default indigo tint lands on a mid denim blue */
.fam-denim {
  background-color: var(--fam-denim-tint, #41619b);
  background-image: var(--fam-tex-denim-tile);
  background-size: 256px;
  background-blend-mode: multiply;
}

/* Lifted slightly so small dark engraved text passes contrast */
.fam-wood {
  background:
    linear-gradient(rgba(255, 238, 205, .22), rgba(255, 238, 205, .22)),
    var(--fam-tex-wood-light-tile) 0 0 / 380px repeat;
}

/* Dark horizontal planks; the tile holds six whole planks, so a 380px repeat gives planks about 63px tall */
.fam-wood-paneled {
  background: var(--fam-tex-wood-paneled-tile) 0 0 / 380px repeat;
}

.fam-metal-brushed {
  background:
    linear-gradient(rgba(255, 255, 255, .3), rgba(255, 255, 255, 0) 45%, rgba(0, 0, 0, .1)),
    var(--fam-tex-metal-tile) 0 0 / 300px repeat;
}

.fam-metal {
  background:
    linear-gradient(rgba(255, 255, 255, .3), rgba(255, 255, 255, 0) 45%, rgba(0, 0, 0, .1)),
    var(--fam-tex-metal-sandblasted) 0 0 / 300px repeat;
}

/* Cream satin plastic, the case in references/plastic.png: a gradient carries the shape and the grain adds texture. The cream is muted and the grain
   stronger than on colored plastic, because a soft-light blend barely shows on a pale base. Use it with a fam-round class. */
.fam-plastic-panel {
  color: #2a2518;
  background:
    var(--fam-tex-grain-plastic) 0 0 / 128px 128px,
    linear-gradient(to bottom, #f1ebd9, #ded5bb 70%, #cec4a8);
  background-blend-mode: soft-light, normal;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .9), inset 0 -2px 6px rgba(0, 0, 0, .18), 0 3px 8px rgba(0, 0, 0, .35);
}

/* The tan wash lets a dark engraved glyph reach contrast on leather */
.fam-leather {
  background:
    linear-gradient(rgba(240, 190, 130, .5), rgba(240, 190, 130, .5)),
    var(--fam-tex-leather-tile) 0 0 / 360px repeat;
}

/* The tile is already light cardstock, so white leaves it natural and any other tint multiplies onto it */
.fam-cardstock {
  background: var(--fam-tex-cardstock-tile) 0 0 / 256px repeat, var(--fam-cardstock-tint, #fff);
  background-blend-mode: multiply;
}

/* The tile repeats at 585px wide so its 27.2px rule pitch scales to exactly 24px, the pad's line height */
.fam-legal-pad {
  background:
    linear-gradient(90deg, transparent 38px, #cc2a2e 38px, #cc2a2e 39px, transparent 39px, transparent 42px, #cc2a2e 42px, #cc2a2e 43px, transparent 43px),
    #fbee9c var(--fam-tex-legal-tile) 0 0 / 585px auto repeat;
}

.fam-paper {
  background: #f7f6f2 var(--fam-tex-paper-tile) 0 0 / 256px repeat;
}

/* Linerboard with faint ridges */
.fam-cardboard {
  background: var(--fam-tex-cardboard-tile) 0 0 / 256px repeat;
}

/* The tile holds 12 rules, so a 324px repeat spaces them 27px apart, a notebook's line height. The margin is a line CSS draws, because a tile
   repeats sideways and could not hold a single vertical one; its pink is the margin line in the photo. */
.fam-lined-paper {
  background:
    linear-gradient(90deg, transparent 44px, #e4708f 44px, #e4708f 45px, transparent 45px),
    var(--fam-tex-lined-paper-tile) 0 0 / 324px repeat;
}

/* The tile holds 12 squares across and down, so a 288px repeat makes them 24px */
.fam-grid-paper {
  background: var(--fam-tex-grid-paper-tile) 0 0 / 288px repeat;
}

/* A slate board wiped with a cloth, with chalk dust left in the strokes */
.fam-blackboard {
  background: #303030 var(--fam-tex-blackboard-tile) 0 0 / 256px repeat;
}

/* The green board of a classroom, with faint wiped chalk */
.fam-chalkboard {
  background: #335f4f var(--fam-tex-chalkboard-tile) 0 0 / 256px repeat;
}

.fam-paper-bag {
  background: var(--fam-tex-paper-bag-tile) 0 0 / 256px repeat;
}

.fam-cork {
  background: #b9763c var(--fam-tex-cork-tile) 0 0 / 256px repeat;
}

/* 9-slice photo frame: 457px image, slice 68 device px, 34px border */
.fam-leather-frame {
  border: 34px solid transparent;
  border-radius: 34px;
  border-image: var(--fam-tex-leather-frame-tan-soft) 68 / 34px / 0 round;
  background: var(--fam-tex-leather-fill-tan-tile) 0 0 / 168px 51.5px repeat;
  box-shadow: 0 22px 36px -14px rgba(0, 0, 0, .65);
}

.fam-leather-frame--black {
  border-image: var(--fam-tex-leather-frame-black-soft) 68 / 34px / 0 round;
  background: var(--fam-tex-leather-fill-black-tile) 0 0 / 168px 51.5px repeat;
  box-shadow: 0 26px 44px -16px rgba(0, 0, 0, .7);
}

.fam-leather-frame--brown {
  border-image: var(--fam-tex-leather-frame-brown-soft) 68 / 34px / 0 round;
  background: var(--fam-tex-leather-fill-brown-tile) 0 0 / 168px 51.5px repeat;
  box-shadow: 0 26px 44px -16px rgba(0, 0, 0, .7);
}

/* A bar of the frame's leather with its stitched edge along the bottom. The 321x50 edge strip is drawn at half size so it stays sharp on 2x screens,
   which puts the stitch row about 8.5px above the bottom edge. */
.fam-leather-bar {
  background:
    var(--fam-tex-leather-bar-edge-tan) 0 100% / auto 25px repeat-x,
    var(--fam-tex-leather-fill-tan-tile) 0 0 / 168px 51.5px repeat;
}

.fam-leather-bar--black {
  background:
    var(--fam-tex-leather-bar-edge-black) 0 100% / auto 25px repeat-x,
    var(--fam-tex-leather-fill-black-tile) 0 0 / 168px 51.5px repeat;
}

.fam-leather-bar--brown {
  background:
    var(--fam-tex-leather-bar-edge-brown) 0 100% / auto 25px repeat-x,
    var(--fam-tex-leather-fill-brown-tile) 0 0 / 168px 51.5px repeat;
}

/* The frame's leather on its own, with no stitched edge */
.fam-leather-pebbled {
  background: var(--fam-tex-leather-fill-tan-tile) 0 0 / 168px 51.5px repeat;
}

.fam-leather-pebbled--black {
  background: var(--fam-tex-leather-fill-black-tile) 0 0 / 168px 51.5px repeat;
}

.fam-leather-pebbled--brown {
  background: var(--fam-tex-leather-fill-brown-tile) 0 0 / 168px 51.5px repeat;
}

/* 9-slice wood frame: 402px square image, 51 device px slices, drawn at half size so a 26px border stays sharp on 2x screens.
   The ::after overlay sits over the content, so it can put the inset shadow where the content meets the frame and, for --glossy, a sheen over the image. */
.fam-wood-frame {
  --fam-frame-width: 26px;
  position: relative;
  border: var(--fam-frame-width) solid transparent;
  border-image: var(--fam-tex-wood-frame) 51 / var(--fam-frame-width) / 0 stretch;
  background: #2b1a10;
  box-shadow: 0 2px 4px rgba(0, 0, 0, .4), 0 22px 36px -12px rgba(0, 0, 0, .65);
}

.fam-wood-frame::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 4px 10px rgba(0, 0, 0, .6), inset 3px 0 8px rgba(0, 0, 0, .35), inset 0 0 0 1px rgba(0, 0, 0, .55);
}

.fam-wood-frame--glossy::after {
  background: linear-gradient(135deg, rgba(255, 255, 255, .3), rgba(255, 255, 255, .08) 42%, transparent 42.5%);
}

.fam-wood-frame > img,
.fam-print-frame > img {
  display: block;
  width: 100%;
  height: auto;
}

/* A print with a margin. The margin is the box's own material, so pair this with fam-paper (white) or fam-cardstock (brown).
   The ::after overlay draws the faint edge around the photo; it spans the padding box minus the margin. */
.fam-print-frame {
  --fam-print-margin: 14px;
  position: relative;
  padding: var(--fam-print-margin);
  box-shadow: 0 1px 1px rgba(0, 0, 0, .25), 0 6px 14px -2px rgba(0, 0, 0, .4), 0 18px 28px -10px rgba(0, 0, 0, .35);
}

.fam-print-frame::after {
  content: '';
  position: absolute;
  inset: var(--fam-print-margin);
  pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .3), inset 0 2px 4px rgba(0, 0, 0, .25);
}

/* ---------- CSS stitched frame: a tintable alternative to the photo frames ---------- */

/* Thread is the leather color lifted toward white by --fam-stitch-lift (about 35% in the Find My Friends reference),
   so the stitching stays consistent on any tint. Set --fam-leather-color to the leather's average color. */
.fam-stitched {
  --fam-leather-color: #8a5a30;
  --fam-stitch-lift: 35%;
  --fam-stitch-color: color-mix(in srgb, white var(--fam-stitch-lift), var(--fam-leather-color));
  --fam-stitch-shadow: color-mix(in srgb, black 55%, var(--fam-leather-color));
  position: relative;
}

/* Running stitches: a 9-slice SVG mask of short rounded thread segments, each tilted slightly along the path, filled with the thread color.
   Corner stitches follow the arc and the period keeps spacing even across corners (corner radius fixed at 16.4px). Generated by make_stitch_svg.py. */
.fam-stitched::after {
  content: '';
  position: absolute;
  inset: var(--fam-stitch-inset, 8px);
  pointer-events: none;
  border: 18px solid transparent;
  background: var(--fam-stitch-color);
  -webkit-mask-box-image-source: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='87.52' height='87.52'%3E%3Cg stroke='black' stroke-width='2.6' stroke-linecap='round'%3E%3Cline x1='0.44' y1='15.23' x2='5.26' y2='8.22'/%3E%3Cline x1='7.55' y1='3.62' x2='15.90' y2='2.07'/%3E%3Cline x1='72.30' y1='0.44' x2='79.30' y2='5.26'/%3E%3Cline x1='83.90' y1='7.55' x2='85.45' y2='15.90'/%3E%3Cline x1='87.08' y1='72.30' x2='82.27' y2='79.30'/%3E%3Cline x1='79.98' y1='83.90' x2='71.62' y2='85.45'/%3E%3Cline x1='15.23' y1='87.08' x2='8.22' y2='82.27'/%3E%3Cline x1='3.62' y1='79.98' x2='2.07' y2='71.62'/%3E%3Cline x1='20.28' y1='0.72' x2='28.60' y2='2.48'/%3E%3Cline x1='86.81' y1='20.28' x2='85.04' y2='28.60'/%3E%3Cline x1='67.24' y1='86.81' x2='58.92' y2='85.04'/%3E%3Cline x1='0.72' y1='67.24' x2='2.48' y2='58.92'/%3E%3Cline x1='33.16' y1='0.72' x2='41.48' y2='2.48'/%3E%3Cline x1='86.81' y1='33.16' x2='85.04' y2='41.48'/%3E%3Cline x1='54.36' y1='86.81' x2='46.04' y2='85.04'/%3E%3Cline x1='0.72' y1='54.36' x2='2.48' y2='46.04'/%3E%3Cline x1='46.04' y1='0.72' x2='54.36' y2='2.48'/%3E%3Cline x1='86.81' y1='46.04' x2='85.04' y2='54.36'/%3E%3Cline x1='41.48' y1='86.81' x2='33.16' y2='85.04'/%3E%3Cline x1='0.72' y1='41.48' x2='2.48' y2='33.16'/%3E%3Cline x1='58.92' y1='0.72' x2='67.24' y2='2.48'/%3E%3Cline x1='86.81' y1='58.92' x2='85.04' y2='67.24'/%3E%3Cline x1='28.60' y1='86.81' x2='20.28' y2='85.04'/%3E%3Cline x1='0.72' y1='28.60' x2='2.48' y2='20.28'/%3E%3C/g%3E%3C/svg%3E");
  -webkit-mask-box-image-slice: 18;
  -webkit-mask-box-image-width: 18px;
  -webkit-mask-box-image-repeat: round;
  filter: drop-shadow(0 1px 0 var(--fam-stitch-shadow));
}

/* Without the mask there is nothing to cut the thread shape, and a dashed border would look wrong */
@supports not (-webkit-mask-box-image-source: none) {
  .fam-stitched::after { display: none; }
}

/* fam-ui effects */

/* Frosted glass. The lens layer and the glow layer are pseudo-elements so the element's own content stays above both.
   The filter layer gets a real border-radius: clip-path and overflow:hidden do not round a backdrop-filter in Chromium. */
.fam-glass {
  --fam-r: initial;
  --fam-bleed: 2rem;
  --fam-glow-depth: 18px;
  --fam-glow-corner: min(var(--fam-r, 0px), 50%);
  --fam-glow-tile: min(calc(var(--fam-glow-corner) * 1000), max(var(--fam-glow-corner), var(--fam-glow-depth)), 50%);
  --fam-shade-inset: 1px;
  --fam-glass-blur: 14px;
  --fam-refract-blur: 1px;
  /* Read by snippets/refraction.js, which sets them on the filter. The static snippet cannot read them and always bends by these defaults. */
  --fam-refract-amount: 1;
  --fam-refract-dispersion: .1;
  --fam-glass-specular: 1;
  --fam-glass-saturate: 125%;
  --fam-glow-blur: calc(var(--fam-glass-blur) + 11px);
  --fam-glow-saturate: 260%;
  --fam-glow-brightness: 150%;
  --fam-refract-saturate: 110%;
  --fam-glass-shade: rgba(0, 0, 0, .42);
  --fam-glass-rim: rgba(255, 255, 255, .28);
  --fam-glass-underlight: rgba(0, 0, 0, .35);
  --fam-glass-ink: #fff;
  --fam-glass-ink-soft: rgba(255, 255, 255, .72);
  --fam-glass-ink-shadow: 0 1px 2px rgba(0, 0, 0, .6);
  position: relative;
  isolation: isolate;
  /* The glow layer's bleed box is 2rem larger on every side. Its paint is already masked to the lens, but the box still counts as
     scrollable overflow, so a full-width field at the viewport edge would scroll the page sideways. */
  overflow: clip;
  border-radius: var(--fam-r, 999px);
  box-shadow: 0 8px 20px -8px rgba(0, 0, 0, .55);
}

/* The dark shade under the highlight is what keeps white text readable on any backdrop, with or without backdrop-filter.
   The transparent border keeps the shade --fam-shade-inset short of the rim: the glow layer samples everything below it, so a shade
   that reached the rim would darken the colors the rim is meant to pick up. Only the shade layer is clipped to the padding box. */
.fam-glass::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border: var(--fam-shade-inset) solid transparent;
  border-radius: inherit;
  backdrop-filter: blur(var(--fam-glass-blur)) saturate(var(--fam-glass-saturate)) brightness(110%);
  background:
    linear-gradient(var(--fam-glass-shade), var(--fam-glass-shade)),
    linear-gradient(to bottom, rgba(255, 255, 255, .3) 0%, rgba(255, 255, 255, .07) 46%, rgba(255, 255, 255, 0) 54%),
    linear-gradient(rgba(255, 255, 255, .14), rgba(255, 255, 255, .32));
  background-origin: border-box;
  background-clip: padding-box, border-box, border-box;
  /* An inset shadow offset toward the light is thickest at the top-left and fades to nothing around the opposite corner, and it follows
     the corner radius, so the rim light needs no geometry of its own. */
  box-shadow:
    inset 3px 3px 3px -2px rgba(255, 255, 255, calc(.95 * var(--fam-glass-specular))),
    inset -2px -2px 3px -2px rgba(255, 255, 255, calc(.4 * var(--fam-glass-specular))),
    inset 0 0 0 1px var(--fam-glass-rim),
    inset 0 -8px 12px -6px var(--fam-glass-underlight);
}

/* Tints change the shade and the ink together, so the text keeps its contrast. Light glass needs dark ink; blue glass keeps white ink.
   Both come after .fam-glass so they win on equal specificity. Refracting glass has no shade, so they only change its ink and rim. */
.fam-glass--light {
  --fam-glass-shade: rgba(255, 255, 255, .5);
  --fam-glass-rim: rgba(255, 255, 255, .5);
  --fam-glass-underlight: rgba(0, 0, 0, .18);
  --fam-glass-ink: #14161c;
  --fam-glass-ink-soft: rgba(20, 22, 28, .86);
  --fam-glass-ink-shadow: 0 1px 0 rgba(255, 255, 255, .6);
}

.fam-glass--blue {
  --fam-glass-shade: var(--fam-glass-blue-shade);
  --fam-glass-rim: rgba(190, 215, 255, .4);
  --fam-glass-underlight: rgba(0, 10, 60, .45);
  --fam-glass-ink-soft: rgba(255, 255, 255, .9);
  --fam-glass-ink-shadow: 0 1px 2px rgba(0, 10, 60, .7);
}

/* Ambient glow. The transparent border is the bleed: the backdrop is sampled across the whole extended box, while the mask
   (four soft edge gradients and four radial corner gradients, clipped to the rounded padding box) keeps a glow that is strongest
   at the lens edge and fades inward over --fam-glow-depth, following the rounded corners. A corner tile is as large as the
   radius, or as the depth when that is larger, so its gradient meets the straight bands exactly and the bands never overlap.
   The tiles are sized per axis, so they are circular only while the box is big enough. CSS cannot take a min across both
   axes, so an unset --fam-r (the default pill, whose radius is always clamped) gets zero-size tiles and keeps the straight bands. */
.fam-glass::after {
  content: '';
  position: absolute;
  inset: calc(-1 * var(--fam-bleed));
  pointer-events: none;
  border: var(--fam-bleed) solid transparent;
  border-radius: calc(var(--fam-r, 999px) + var(--fam-bleed));
  backdrop-filter: blur(var(--fam-glow-blur)) brightness(var(--fam-glow-brightness)) saturate(var(--fam-glow-saturate));
  background: linear-gradient(135deg, rgba(255, 255, 255, .35), rgba(255, 255, 255, .04) 35%, rgba(255, 255, 255, .04) 65%, rgba(255, 255, 255, .3)) padding-box;
  mask:
    linear-gradient(to bottom, #000, rgba(0, 0, 0, .35) calc(var(--fam-glow-depth) * .3), transparent var(--fam-glow-depth)) center top / calc(100% - 2 * var(--fam-glow-tile)) 100% no-repeat padding-box,
    linear-gradient(to top, #000, rgba(0, 0, 0, .35) calc(var(--fam-glow-depth) * .3), transparent var(--fam-glow-depth)) center bottom / calc(100% - 2 * var(--fam-glow-tile)) 100% no-repeat padding-box,
    linear-gradient(to right, #000, rgba(0, 0, 0, .35) calc(var(--fam-glow-depth) * .3), transparent var(--fam-glow-depth)) left center / 100% calc(100% - 2 * var(--fam-glow-tile)) no-repeat padding-box,
    linear-gradient(to left, #000, rgba(0, 0, 0, .35) calc(var(--fam-glow-depth) * .3), transparent var(--fam-glow-depth)) right center / 100% calc(100% - 2 * var(--fam-glow-tile)) no-repeat padding-box,
    radial-gradient(ellipse farthest-side at 100% 100%, transparent calc(100% - var(--fam-glow-depth)), rgba(0, 0, 0, .35) calc(100% - var(--fam-glow-depth) * .3), #000 100%) left top / var(--fam-glow-tile) var(--fam-glow-tile) no-repeat padding-box,
    radial-gradient(ellipse farthest-side at 0 100%, transparent calc(100% - var(--fam-glow-depth)), rgba(0, 0, 0, .35) calc(100% - var(--fam-glow-depth) * .3), #000 100%) right top / var(--fam-glow-tile) var(--fam-glow-tile) no-repeat padding-box,
    radial-gradient(ellipse farthest-side at 100% 0, transparent calc(100% - var(--fam-glow-depth)), rgba(0, 0, 0, .35) calc(100% - var(--fam-glow-depth) * .3), #000 100%) left bottom / var(--fam-glow-tile) var(--fam-glow-tile) no-repeat padding-box,
    radial-gradient(ellipse farthest-side at 0 0, transparent calc(100% - var(--fam-glow-depth)), rgba(0, 0, 0, .35) calc(100% - var(--fam-glow-depth) * .3), #000 100%) right bottom / var(--fam-glow-tile) var(--fam-glow-tile) no-repeat padding-box;
}

/* The glow gathers the colors around the rim through a wide blur, 25px at the default glass blur, and grows with the glass blur so
   turning the blur up softens the rim and the middle together. The offset is smaller for frosted glass because its default blur is wider. */
.fam-glass--refract { --fam-glow-blur: calc(var(--fam-refract-blur) + 22px); }

/* Clear glass that bends the backdrop at its rim. The plain declaration comes first so an engine that rejects url() filters keeps it.
   Chromium only; the displacement filter itself is injected by snippets/refraction.js, or pasted from snippets/refraction-filter.html without it. */
.fam-glass--refract::before {
  backdrop-filter: blur(var(--fam-refract-blur)) saturate(var(--fam-refract-saturate)) brightness(105%);
  backdrop-filter: url(#fam-refract) blur(var(--fam-refract-blur)) saturate(var(--fam-refract-saturate)) brightness(105%);
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, .24) 0%, rgba(255, 255, 255, .05) 46%, rgba(255, 255, 255, 0) 54%),
    linear-gradient(rgba(255, 255, 255, .06), rgba(255, 255, 255, .18));
  background-clip: border-box;
}

/* snippets/refraction.js gives each refracting glass a filter shaped to its own radius and names it in --fam-refract-filter.
   It sits behind @supports because var() always parses: an engine that cannot use url() in a backdrop filter would otherwise drop
   the blur instead of keeping the plain declaration above. */
@supports (backdrop-filter: url(#fam-refract)) {
  .fam-glass--refract::before {
    backdrop-filter: var(--fam-refract-filter, url(#fam-refract)) blur(var(--fam-refract-blur)) saturate(var(--fam-refract-saturate)) brightness(105%);
  }
}

/* The elevation and cast classes also name their shadow in --fam-elevation. A plastic or metal button adds it to the shadows it already draws
   (components.css), because its own box-shadow would otherwise win over the class. */
.fam-shadow-sm { --fam-elevation: var(--fam-shadow-sm); box-shadow: var(--fam-elevation); }
.fam-shadow-md { --fam-elevation: var(--fam-shadow-md); box-shadow: var(--fam-elevation); }
.fam-shadow-lg { --fam-elevation: var(--fam-shadow-lg); box-shadow: var(--fam-elevation); }
.fam-shadow-inset { box-shadow: var(--fam-shadow-inset); }

.fam-cast-sm { --fam-elevation: var(--fam-cast-sm); box-shadow: var(--fam-elevation); }
.fam-cast-md { --fam-elevation: var(--fam-cast-md); box-shadow: var(--fam-elevation); }
.fam-cast-lg { --fam-elevation: var(--fam-cast-lg); box-shadow: var(--fam-elevation); }

/* An element resting on its surface: a thin flat ellipse just under the bottom edge. It uses ::after, so an element that already uses it
   (the pill, the glass, the frames, round plastic) takes the class on a wrapper instead. The ellipse has no negative z-index, because that would
   hide it behind the background of whatever surface the element sits on. It starts at the bottom edge on purpose, so painting above the
   element never covers its face. */
.fam-grounded-sm { --fam-grounded-width: 80%; --fam-grounded-height: 6px; --fam-grounded-strength: 50%; --fam-grounded-gap: 0px; }
.fam-grounded-md { --fam-grounded-width: 88%; --fam-grounded-height: 8px; --fam-grounded-strength: 60%; --fam-grounded-gap: 0px; }
.fam-grounded-lg { --fam-grounded-width: 96%; --fam-grounded-height: 12px; --fam-grounded-strength: 70%; --fam-grounded-gap: 2px; }

/* Zero specificity, so an element positioned by its own class or inline style keeps that position */
:where(.fam-grounded-sm, .fam-grounded-md, .fam-grounded-lg) { position: relative; }

:is(.fam-grounded-sm, .fam-grounded-md, .fam-grounded-lg)::after {
  content: '';
  position: absolute;
  top: calc(100% - 1px + var(--fam-grounded-gap));
  left: calc((100% - var(--fam-grounded-width)) / 2);
  width: var(--fam-grounded-width);
  height: var(--fam-grounded-height);
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(
    ellipse at 50% 50%,
    color-mix(in srgb, var(--fam-grounded-ink, rgb(0 0 0)) var(--fam-grounded-strength), transparent) 0%,
    color-mix(in srgb, var(--fam-grounded-ink, rgb(0 0 0)) calc(var(--fam-grounded-strength) / 2), transparent) 45%,
    transparent 72%
  );
}

/* A flipped copy of the element fades out below it, like a glossy floor. -webkit-box-reflect works in Chromium and Safari; Firefox does
   not support it and draws no reflection, which only loses the decoration. The reflection takes no layout space, so leave room under the element. */
.fam-reflect { -webkit-box-reflect: below 2px linear-gradient(transparent 40%, rgba(255, 255, 255, .5)); }

/* A shiny floor along the bottom of a box, with a bright top edge, for dark surfaces. It is half the box tall; set --fam-shelf-height and the
   same padding-bottom to make the things standing in the box rest on its top edge. It uses ::before behind the content, so a box that
   already uses ::before takes the class on a wrapper. Zero specificity on position keeps a box positioned by its own class or inline style. */
:where(.fam-shelf) { position: relative; }

.fam-shelf { isolation: isolate; }

.fam-shelf::before {
  content: '';
  position: absolute;
  z-index: -1;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--fam-shelf-height, 50%);
  border-top: 1px solid rgba(255, 255, 255, .35);
  border-bottom-left-radius: inherit;
  border-bottom-right-radius: inherit;
  background: linear-gradient(rgba(255, 255, 255, .16), rgba(255, 255, 255, .03) 40%, rgba(0, 0, 0, .35));
  pointer-events: none;
}

/* All but the pill also set --fam-r so a fam-glass glow follows the same radius. This relies on coming after .fam-glass.
   The pill is the glass default, which leaves --fam-r unset. */
.fam-round-sm { --fam-r: var(--fam-radius-sm); border-radius: var(--fam-radius-sm); }
.fam-round-md { --fam-r: var(--fam-radius-md); border-radius: var(--fam-radius-md); }
.fam-round-lg { --fam-r: var(--fam-radius-lg); border-radius: var(--fam-radius-lg); }
.fam-round-pill { border-radius: var(--fam-radius-pill); }

/* An inner box inside padding looks even when its radius is the outer radius minus the padding */
.fam-concentric { border-radius: calc(var(--fam-outer-radius) - var(--fam-pad)); }

/* Aqua pill: dark rim, a body that gets lighter toward the bottom, and a soft sheen in the upper half whose strength is --fam-gloss.
   The glossy button in components.css shares these rules and only changes the colors. */
.fam-pill,
.fam-glossy-button {
  --fam-gloss: .28;
  --fam-aqua-rim: #243fa0;
  --fam-aqua-top: #3556c4;
  --fam-aqua-mid: #5a85ea;
  --fam-aqua-bottom: #8db0f7;
  position: relative;
  overflow: hidden;
  border-radius: var(--fam-radius-pill);
  border: 1px solid var(--fam-aqua-rim);
  background: linear-gradient(to bottom, var(--fam-aqua-top) 0%, var(--fam-aqua-mid) 52%, var(--fam-aqua-bottom) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .45), 0 3px 6px rgba(0, 0, 0, .35);
}

.fam-pill::after,
.fam-glossy-button::after {
  content: '';
  position: absolute;
  left: 4%;
  right: 4%;
  top: 2px;
  height: 50%;
  border-radius: var(--fam-radius-pill);
  background: linear-gradient(rgba(255, 255, 255, var(--fam-gloss)), rgba(255, 255, 255, 0));
  pointer-events: none;
}

.fam-gloss-none {
  --fam-gloss: 0;
  background: linear-gradient(#4574e2, #3a66d4);
}

.fam-gloss-soft { --fam-gloss: .28; }
.fam-gloss-strong { --fam-gloss: .55; }

/* Engraved text: an opaque dark glyph with a light lip along the lower edge, so it looks cut into the surface.
   The glyph colors were fitted to the real texture pixels to pass WCAG contrast as large text (20px bold, 3:1), so the size is part of the class. */
.fam-engraved-metal {
  font-size: 20px;
  color: rgb(18, 20, 26);
  font-weight: 700;
  letter-spacing: 1px;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .9), 0 -1px 0 rgba(0, 0, 0, .2);
}

.fam-engraved-leather {
  font-size: 20px;
  color: rgb(55, 28, 10);
  font-weight: 700;
  letter-spacing: 1px;
  text-shadow: 0 1px 0 rgba(255, 225, 185, .55), 0 -1px 1px rgba(0, 0, 0, .25);
}

/* Light letters pressed into dark leather, like foil stamping. As on the planks, the dark stroke is the shaded wall just inside each letter's edge and the light lip below is the lit lower edge. */
.fam-engraved-leather-dark {
  font-size: 20px;
  color: rgb(236, 227, 207);
  font-weight: 700;
  letter-spacing: 1px;
  -webkit-text-stroke: 1px rgba(0, 0, 0, .7);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .28), 0 -1px 1px rgba(0, 0, 0, .55);
}

/* Light wood showing where the letters were cut. The dark stroke is the groove's shaded wall just inside the edge of each letter, and the light lip below is its lit lower edge.
   A text shadow can only fall outside the glyph, so on its own it makes light letters look raised. */
.fam-engraved-wood-paneled {
  font-size: 20px;
  color: rgb(244, 218, 176);
  font-weight: 700;
  letter-spacing: 1px;
  -webkit-text-stroke: 1px rgba(58, 26, 8, .85);
  text-shadow: 0 1px 0 rgba(255, 222, 176, .55), 0 -1px 1px rgba(0, 0, 0, .6);
}

.fam-engraved-wood {
  font-size: 20px;
  color: rgb(66, 38, 14);
  font-weight: 700;
  letter-spacing: 1px;
  text-shadow: 0 1px 0 rgba(255, 238, 205, .55), 0 -1px 1px rgba(0, 0, 0, .25);
}

/* fam-ui components */

/* Touch screens flash a gray box over a tapped control. The kit's controls show their own pressed and selected looks, and :where() keeps this
   from outranking any rule of yours. The property is inherited, so the parts inside a control are covered too. */
:where([class^="fam-"], [class*=" fam-"]) { -webkit-tap-highlight-color: transparent; }

/* ---------- Glass fields and the dropdown menu ---------- */

.fam-glass-input {
  box-sizing: border-box;
  position: relative;
  z-index: 1;
  width: 100%;
  padding: 10px 18px;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--fam-glass-ink);
  font: inherit;
  text-shadow: var(--fam-glass-ink-shadow);
}

.fam-glass-input::placeholder { color: var(--fam-glass-ink-soft); }

/* Clear glass has no frosting behind the placeholder, and its sheen brightens the backdrop, so the soft ink falls under 4.5:1 */
.fam-glass--refract .fam-glass-input::placeholder { color: var(--fam-glass-ink); }

/* iOS Safari zooms the page when a field under 16px gets focus */
@media (pointer: coarse) {
  .fam-glass-input { font-size: max(1em, 16px); }
}

/* The dropdown is the glass field with a plain white chevron and no separate button */
select.fam-glass-input {
  appearance: none;
  padding-right: 42px;
  cursor: pointer;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1.5 1.5 6 6l4.5-4.5' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") right 18px center / 12px 8px no-repeat;
}

/* The native popup is drawn on a light surface, so its options cannot inherit the field's white text */
select.fam-glass-input option { color: #222; text-shadow: none; }

.fam-glass--light select.fam-glass-input {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1.5 1.5 6 6l4.5-4.5' fill='none' stroke='%2314161c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

.fam-glass:has(.fam-glass-input:focus-visible) {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
  box-shadow: var(--fam-focus-halo), 0 8px 20px -8px rgba(0, 0, 0, .55);
}

.fam-menu {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(250, 250, 250, .94);
  color: #222;
  box-shadow: 0 10px 24px -6px rgba(0, 0, 0, .6), 0 0 0 1px rgba(0, 0, 0, .35);
}

.fam-menu > li { padding: 7px 14px; }

/* The selected row is the solid blue family, with no gloss */
.fam-menu > [aria-selected="true"] {
  color: #fff;
  text-shadow: 0 -1px 0 rgba(0, 30, 110, .8);
  background: linear-gradient(to bottom, var(--fam-blue-top), var(--fam-blue-bottom));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3);
}

/* ---------- Metal switch: a checkbox, so it toggles with no JavaScript ----------
   The thumb is 8px taller than the track and sticks out 4px past each end, so the track does not clip anything and the
   margin keeps neighbours clear of the overhang. */

.fam-switch {
  box-sizing: border-box;
  position: relative;
  display: inline-block;
  width: 78px;
  height: 28px;
  margin: 4px;
  border-radius: var(--fam-radius-pill);
  cursor: pointer;
  background: var(--fam-tex-metal-brushed) 50% 50% / 240px auto;
  /* Every state lists the same five shadows in the same order, which is what lets the browser animate between them */
  --fam-rest-shadow: inset 0 3px 7px rgba(0, 0, 0, .75), inset 0 -1px 1px rgba(255, 255, 255, .35), 0 1px 0 rgba(255, 255, 255, .25), 0 0 0 1px rgba(0, 0, 0, .7), 0 0 12px 2px rgba(100, 140, 245, 0);
  box-shadow: var(--fam-rest-shadow);
  /* The track is sunken, so a fam-shadow or fam-cast class on the switch lifts the thumb instead. --fam-elevation does not inherit, so the
     label hands it down in a variable that does. */
  --fam-thumb-elevation: var(--fam-elevation, 0 0 0 0 transparent);
  transition: box-shadow .22s ease;
}

/* The native input covers the whole track, invisible but focusable and clickable */
.fam-switch input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: inherit;
}

.fam-switch::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  opacity: 0;
  transition: opacity .22s ease;
  background:
    linear-gradient(rgba(255, 255, 255, .35), rgba(255, 255, 255, 0) 50%),
    linear-gradient(to bottom, rgba(64, 110, 218, .95), rgba(122, 157, 245, .92));
}

.fam-switch-knob {
  --fam-thumb-shadow: 0 0 9px 1px rgba(150, 175, 252, 0), 0 2px 4px rgba(0, 0, 0, .65), inset 0 -2px 3px rgba(0, 0, 0, .35), inset 0 1px 1px rgba(255, 255, 255, .9), 0 0 0 1px rgba(0, 0, 0, .45);
  position: absolute;
  top: -4px;
  left: -4px;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 18%, rgba(255, 255, 255, .35) 0%, rgba(255, 255, 255, 0) 55%),
    var(--fam-tex-metal-spiral) 50% 50% / auto 108px;
  box-shadow: var(--fam-thumb-shadow), var(--fam-thumb-elevation);
  transition: left .22s cubic-bezier(.4, 0, .2, 1), box-shadow .22s ease;
}

.fam-switch:has(input:checked) {
  --fam-rest-shadow: inset 0 3px 7px rgba(0, 30, 110, .5), inset 0 0 14px rgba(160, 185, 252, .85), 0 1px 0 rgba(255, 255, 255, .25), 0 0 0 1px rgba(20, 40, 120, .85), 0 0 12px 2px rgba(100, 140, 245, .7);
}

.fam-switch:has(input:checked)::before { opacity: 1; }

.fam-switch:has(input:checked) .fam-switch-knob {
  --fam-thumb-shadow: 0 0 9px 1px rgba(150, 175, 252, .85), 0 2px 4px rgba(0, 0, 0, .55), inset 0 -2px 3px rgba(0, 0, 0, .35), inset 0 1px 1px rgba(255, 255, 255, .9), 0 0 0 1px rgba(0, 40, 130, .6);
  left: calc(100% - 32px);
}

/* The outline sits 6px out so it clears the 4px the thumb sticks out; outlines paint above the thumb */
.fam-switch:has(input:focus-visible) {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 6px;
  box-shadow: var(--fam-focus-halo), var(--fam-rest-shadow);
}

@media (prefers-reduced-motion: reduce) {
  .fam-switch,
  .fam-switch::before,
  .fam-switch-knob { transition: none; }
}

/* ---------- Progress tubes. Set the value with --fam-value on the tube. ---------- */

.fam-progress {
  box-sizing: border-box;
  position: relative;
  height: 18px;
  border-radius: var(--fam-radius-pill);
  overflow: hidden;
  background: linear-gradient(to bottom, rgba(0, 0, 0, .55), rgba(0, 0, 0, .25));
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .7), 0 1px 0 rgba(255, 255, 255, .25), 0 0 0 1px rgba(0, 0, 0, .5);
}

/* Aqua gloss lives in the gradient: a dark thin top edge, a pale highlight band, a saturated middle and a light glow at the bottom */
.fam-progress-fill {
  --fam-sheen: linear-gradient(to bottom, rgba(20, 45, 150, .55) 0%, rgba(20, 45, 150, 0) 16%, rgba(255, 255, 255, .38) 30%, rgba(255, 255, 255, .12) 52%, rgba(255, 255, 255, 0) 60%, rgba(140, 180, 255, .3) 100%);
  position: absolute;
  inset: 1px;
  right: auto;
  width: var(--fam-value, 0%);
  border-radius: var(--fam-radius-pill);
}

/* Soft-edged diagonal stripes with a 32px period under the sheen. The tile is 32px / sin(45deg) = 45.25px so the one-second loop is seamless. */
.fam-progress-fill--candy {
  background:
    var(--fam-sheen),
    repeating-linear-gradient(-45deg, #3d6fe0 0, #3d6fe0 6px, #f4f8ff 10px, #f4f8ff 22px, #3d6fe0 26px, #3d6fe0 32px);
  background-size: 100% 100%, 45.25px 45.25px;
  background-repeat: no-repeat, repeat;
  animation: fam-stripe 1s linear infinite;
  box-shadow: inset 0 0 0 1px rgba(20, 40, 140, .35);
}

@keyframes fam-stripe {
  from { background-position: 0 0, 0 0; }
  to { background-position: 0 0, 45.25px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .fam-progress-fill--candy { animation: none; }
}

.fam-progress-fill--aqua {
  background: linear-gradient(to bottom, #2b4fb5 0%, #93aef0 14%, #a3bbf2 38%, #4a78e4 58%, #5f8bec 80%, #86abf6 100%);
  box-shadow: inset 0 0 0 1px rgba(20, 40, 140, .35);
}

.fam-progress-fill--green {
  background: linear-gradient(to bottom, #1f7a32 0%, #9fd9a4 14%, #b0e2b3 38%, #35b24a 58%, #4cc562 80%, #7ae08c 100%);
  box-shadow: inset 0 0 0 1px rgba(10, 80, 30, .35);
}

/* ---------- Plastic buttons and the metal knob ---------- */

/* Satin plastic: the gradient and the shadows carry the shape, and a fine grain blended softly over them only adds texture.
   isolation keeps the dish (z-index -1) above the face and below the label. */
.fam-plastic {
  --fam-c: #264eae;
  --fam-grain: var(--fam-tex-grain-fine);
  box-sizing: border-box;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  height: 34px;
  padding: 0 18px;
  border-radius: var(--fam-radius-pill);
  color: #fff;
  font: 600 13px/1 var(--fam-font-ui);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .45);
  cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--fam-c) 40%, black);
  background:
    var(--fam-grain) 0 0 / 128px 128px,
    linear-gradient(to bottom, color-mix(in srgb, var(--fam-c) 88%, white) 0%, color-mix(in srgb, var(--fam-c) 97%, white) 38%, var(--fam-c) 62%, color-mix(in srgb, var(--fam-c) 80%, black) 100%);
  background-blend-mode: soft-light, normal;
  --fam-rest-shadow: inset 0 1px 0 rgba(255, 255, 255, .4), inset 0 -2px 3px rgba(0, 0, 0, .25), 0 2px 3px rgba(0, 0, 0, .4);
  /* The collar the button is set in, as in references/plastic.png: a dark gap where the button meets it, the light collar, a shaded edge
     below it and the shadow it casts. Cells of a group sit in a well instead. */
  --fam-ring-gap: rgba(0, 0, 0, .22);
  --fam-ring:
    0 0 0 2px var(--fam-ring-gap),
    0 0 0 5px rgba(255, 255, 255, .3),
    0 1px 0 6px rgba(0, 0, 0, .1),
    0 3px 6px 4px rgba(0, 0, 0, .08);
  /* --fam-elevation comes from a fam-shadow or fam-cast class. It goes last so the collar sits over it, and only the resting and focused
     states carry it: a pressed or disabled button has sunk into its case. */
  box-shadow: var(--fam-rest-shadow), var(--fam-ring), var(--fam-elevation, 0 0 0 0 transparent);
}

.fam-plastic::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(110% 80% at 50% 0%, rgba(255, 255, 255, .06), rgba(255, 255, 255, 0) 70%);
  pointer-events: none;
}

.fam-plastic:focus-visible {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
  box-shadow: var(--fam-focus-halo), var(--fam-rest-shadow), var(--fam-ring), var(--fam-elevation, 0 0 0 0 transparent);
}

/* Pressed, the button sinks into its collar: the face goes inset and the gap darkens, and the collar stays where it is */
.fam-plastic:active:not(:disabled) {
  --fam-ring-gap: rgba(0, 0, 0, .42);
  box-shadow: inset 0 3px 6px rgba(0, 0, 0, .5), inset 0 -1px 0 rgba(255, 255, 255, .18), var(--fam-ring);
}

.fam-plastic--red { --fam-c: #a82219; }
.fam-plastic--green { --fam-c: #176528; }
.fam-plastic--blue { --fam-c: #264eae; }
.fam-plastic--purple { --fam-c: #53349e; }

/* The cream plastic of the case and the buttons in references/plastic.png; a pale face needs a dark label */
.fam-plastic--cream {
  --fam-c: #e1dac4;
  --fam-grain: var(--fam-tex-grain-plastic);
  color: #2a2518;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .6);
}

/* White cannot reach contrast on orange, so amber takes a dark label */
.fam-plastic--amber {
  --fam-c: #f2a62b;
  color: #2a1600;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .35);
}

/* A button that has not popped up yet: sunk into its case with a darker face, a muted label and no outer shadow */
.fam-plastic:disabled {
  opacity: .7;
  cursor: default;
  color: rgba(255, 255, 255, .5);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
  background:
    var(--fam-grain) 0 0 / 128px 128px,
    linear-gradient(to bottom, color-mix(in srgb, var(--fam-c) 55%, black) 0%, color-mix(in srgb, var(--fam-c) 48%, black) 100%);
  background-blend-mode: soft-light, normal;
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, .6), inset 0 -1px 0 rgba(255, 255, 255, .18), var(--fam-ring);
}

/* Metal button: the sandblasted metal photo under a soft top light, with the same case, dish and disabled look as the plastic ones */
.fam-metal-button {
  box-sizing: border-box;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  height: 34px;
  padding: 0 18px;
  border-radius: var(--fam-radius-pill);
  border: 1px solid rgba(0, 0, 0, .55);
  color: rgb(18, 20, 26);
  font: 600 13px/1 var(--fam-font-ui);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .7);
  cursor: pointer;
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, .72) 0%, rgba(255, 255, 255, .58) 50%, rgba(255, 255, 255, .4) 100%),
    var(--fam-tex-metal-sandblasted) 50% 50% / 240px auto;
  --fam-rest-shadow: inset 0 1px 0 rgba(255, 255, 255, .8), inset 0 -2px 3px rgba(0, 0, 0, .25), 0 2px 3px rgba(0, 0, 0, .45);
  box-shadow: var(--fam-rest-shadow), var(--fam-elevation, 0 0 0 0 transparent);
}

.fam-metal-button:focus-visible {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
  box-shadow: var(--fam-focus-halo), var(--fam-rest-shadow), var(--fam-elevation, 0 0 0 0 transparent);
}

.fam-metal-button:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .45), 0 1px 1px rgba(0, 0, 0, .4);
}

.fam-metal-button:disabled {
  opacity: .7;
  cursor: default;
  color: rgba(18, 20, 26, .45);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .3);
  background:
    linear-gradient(rgba(0, 0, 0, .38), rgba(0, 0, 0, .38)),
    var(--fam-tex-metal-sandblasted) 50% 50% / 240px auto;
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, .6), inset 0 -1px 0 rgba(255, 255, 255, .25);
}

/* The brushed variant swaps only the photo; the case, dish and disabled look stay the metal button's */
.fam-metal-button--brushed {
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, .72) 0%, rgba(255, 255, 255, .58) 50%, rgba(255, 255, 255, .4) 100%),
    var(--fam-tex-metal-brushed) 50% 50% / 240px auto;
}

.fam-metal-button--brushed:disabled {
  background:
    linear-gradient(rgba(0, 0, 0, .38), rgba(0, 0, 0, .38)),
    var(--fam-tex-metal-brushed) 50% 50% / 240px auto;
}

/* Wooden button: the light wood photo under a soft top light, with the metal button's case, shape and disabled look. Its ink is the
   dark engraved ink of the wooden navigation bar. */
.fam-wood-button {
  box-sizing: border-box;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  height: 34px;
  padding: 0 18px;
  border-radius: var(--fam-radius-pill);
  border: 1px solid rgba(50, 25, 5, .7);
  color: #1c0d03;
  font: 600 13px/1 var(--fam-font-ui);
  text-shadow: 0 1px 0 rgba(255, 238, 205, .6), 0 -1px 0 rgba(60, 30, 5, .3);
  cursor: pointer;
  background:
    linear-gradient(to bottom, rgba(255, 238, 205, .5) 0%, rgba(255, 238, 205, .36) 50%, rgba(255, 238, 205, .22) 100%),
    var(--fam-tex-wood-light-tile) 0 0 / 380px repeat;
  --fam-rest-shadow: inset 0 1px 0 rgba(255, 244, 220, .7), inset 0 -2px 3px rgba(80, 40, 10, .35), 0 2px 3px rgba(0, 0, 0, .45);
  box-shadow: var(--fam-rest-shadow), var(--fam-elevation, 0 0 0 0 transparent);
}

.fam-wood-button:focus-visible {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
  box-shadow: var(--fam-focus-halo), var(--fam-rest-shadow), var(--fam-elevation, 0 0 0 0 transparent);
}

.fam-wood-button:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 2px 4px rgba(40, 20, 5, .5), 0 1px 1px rgba(0, 0, 0, .4);
}

.fam-wood-button:disabled {
  opacity: .7;
  cursor: default;
  color: rgba(28, 13, 3, .5);
  text-shadow: 0 1px 0 rgba(255, 238, 205, .3);
  background:
    linear-gradient(rgba(0, 0, 0, .38), rgba(0, 0, 0, .38)),
    var(--fam-tex-wood-light-tile) 0 0 / 380px repeat;
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, .6), inset 0 -1px 0 rgba(255, 244, 220, .25);
}

/* The paneled variant swaps the photo for the dark planks and the ink for the light engraved ink of the paneled bar */
.fam-wood-button--paneled {
  color: rgb(244, 218, 176);
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .8);
  background:
    linear-gradient(to bottom, rgba(255, 222, 176, .16) 0%, rgba(255, 222, 176, 0) 60%),
    var(--fam-tex-wood-paneled-tile) 0 0 / 380px repeat;
}

.fam-wood-button--paneled:disabled {
  color: rgba(244, 218, 176, .5);
  background:
    linear-gradient(rgba(0, 0, 0, .38), rgba(0, 0, 0, .38)),
    var(--fam-tex-wood-paneled-tile) 0 0 / 380px repeat;
}

/* Round and square buttons of every family. They come after the base rules so their size wins. */
.fam-plastic--round,
.fam-plastic--square,
.fam-metal-button--round,
.fam-metal-button--square,
.fam-wood-button--round,
.fam-wood-button--square {
  width: 34px;
  min-width: 0;
  padding: 0;
  font-size: 20px;
}

.fam-plastic--square,
.fam-metal-button--square,
.fam-wood-button--square {
  border-radius: var(--fam-radius-md);
  font-size: 16px;
}

/* The glyph stays inside the dish, because the dish's light lip would run through a larger one and cost it contrast */
.fam-plastic--round { font-size: 16px; }

/* The round dish in the middle of a round or square plastic button (metal buttons have none), as in the cells of the grouped strip in references/plastic.png */
.fam-plastic--round::after,
.fam-plastic--square::after {
  content: '';
  position: absolute;
  inset: 5px;
  z-index: -1;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 30%, rgba(0, 0, 0, .18), rgba(0, 0, 0, 0) 75%);
  box-shadow: inset 0 2px 3px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .35);
  pointer-events: none;
}

/* ---------- Glossy and glass buttons ---------- */

/* The gradient, rim and sheen come from the aqua pill in effects.css; the lighter blue keeps the dark label above 4.5:1.
   The sheen goes behind the label so it never washes the text. */
.fam-glossy-button {
  --fam-aqua-rim: #2a4aa8;
  --fam-aqua-top: #6a98f2;
  --fam-aqua-mid: #86acf7;
  --fam-aqua-bottom: #bcd3fb;
  box-sizing: border-box;
  isolation: isolate;
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  height: 34px;
  padding: 0 18px;
  color: rgb(8, 20, 60);
  font: 600 13px/1 var(--fam-font-ui);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .55);
  cursor: pointer;
  --fam-rest-shadow: inset 0 1px 0 rgba(255, 255, 255, .6), 0 2px 4px rgba(0, 0, 0, .4);
  box-shadow: var(--fam-rest-shadow);
}

.fam-glossy-button::after { z-index: -1; }

/* The gray gloss of the toolbar buttons in the Panther and iTunes screenshots */
.fam-glossy-button--silver {
  --fam-aqua-rim: #787c84;
  --fam-aqua-top: #fcfcfd;
  --fam-aqua-mid: #e4e6ea;
  --fam-aqua-bottom: #c6cad1;
  color: rgb(20, 22, 28);
}

.fam-glossy-button:focus-visible {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
  box-shadow: var(--fam-focus-halo), var(--fam-rest-shadow);
}

.fam-glossy-button:active:not(:disabled) {
  transform: translateY(1px);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .35), 0 1px 1px rgba(0, 0, 0, .4);
}

/* A glass button is the glass pill on a button element. The glow goes behind the label like the lens layer. */
.fam-glass-button {
  box-sizing: border-box;
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  height: 34px;
  padding: 0 20px;
  border: 0;
  background: none;
  color: var(--fam-glass-ink);
  font: 600 13px/1 var(--fam-font-ui);
  text-shadow: var(--fam-glass-ink-shadow);
  cursor: pointer;
}

.fam-glass-button::after { z-index: -1; }

.fam-glass-button:focus-visible {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
  box-shadow: var(--fam-focus-halo), 0 8px 20px -8px rgba(0, 0, 0, .55);
}

.fam-glass-button:active:not(:disabled) { transform: translateY(1px); }

/* ---------- Radio buttons ----------
   A real radio input sits invisibly over the dot, so grouping, arrow keys and form behavior come from the browser.
   Plastic and metal dots light an orange LED when checked; glossy and glass dots show a plain dot. */

/* The label sits on a light capsule with the dot at its left end: the dark label alone fell under 4.5:1 on the darkest brushed streaks */
.fam-radio {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 4px 14px 4px 0;
  padding: 3px 12px 3px 3px;
  border-radius: var(--fam-radius-pill);
  background: rgba(255, 255, 255, .32);
  cursor: pointer;
  font: 600 13px/1.2 var(--fam-font-ui);
  color: rgb(18, 20, 26);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .8);
}

.fam-radio input {
  position: absolute;
  left: 0;
  top: 50%;
  width: 22px;
  height: 22px;
  margin: -11px 0 0 3px;
  opacity: 0;
  cursor: inherit;
}

@media (pointer: coarse) {
  .fam-radio {
    box-sizing: border-box;
    min-height: 44px;
  }
}

.fam-radio-dot {
  box-sizing: border-box;
  position: relative;
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
}

.fam-radio-dot::after {
  content: '';
  position: absolute;
  inset: 5px;
  border-radius: 50%;
}

.fam-radio:has(input:focus-visible) .fam-radio-dot {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
}

/* The cream plastic and the brushed metal share the dish and the LED. Every state lists the same five shadows so they can fade. */
.fam-radio--plastic .fam-radio-dot,
.fam-radio--metal .fam-radio-dot {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .8), inset 0 -2px 3px rgba(0, 0, 0, .2), 0 2px 3px rgba(0, 0, 0, .4), 0 0 0 1px rgba(0, 0, 0, .45), 0 0 0 0 transparent, inset 0 0 0 0 transparent;
  transition: box-shadow .5s ease-out;
}

.fam-radio--plastic .fam-radio-dot {
  background:
    var(--fam-tex-grain-plastic) 0 0 / 128px 128px,
    linear-gradient(to bottom, #f4efdd, #dcd3b8 60%, #c8bea2);
  background-blend-mode: soft-light, normal;
}

.fam-radio--metal .fam-radio-dot {
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, .6), rgba(255, 255, 255, .3)),
    var(--fam-tex-metal-brushed) 50% 50% / 240px auto;
}

/* The unlit lens is the dot's ::before and the lit lens its ::after, which fades in over it */
.fam-radio--plastic .fam-radio-dot::before,
.fam-radio--metal .fam-radio-dot::before {
  content: '';
  position: absolute;
  inset: 5px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12), inset 0 -1px 2px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .6);
  background: var(--fam-led-unlit-face);
  background-blend-mode: normal, multiply, normal;
}

.fam-radio--plastic .fam-radio-dot::after,
.fam-radio--metal .fam-radio-dot::after {
  background: var(--fam-led-lit-face);
  background-blend-mode: normal, multiply, normal;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .25), 0 0 5px 1px #ffb273, 0 0 9px 2px rgba(255, 106, 31, .8);
  opacity: 0;
  transition: opacity .5s ease-out;
}

.fam-radio--plastic input:checked + .fam-radio-dot,
.fam-radio--metal input:checked + .fam-radio-dot {
  transition-duration: .12s;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .8), inset 0 -2px 3px rgba(0, 0, 0, .2), 0 2px 3px rgba(0, 0, 0, .4), 0 0 0 1px rgba(0, 0, 0, .45), 0 0 14px 3px rgba(255, 106, 31, .75), inset 0 0 10px rgba(255, 140, 70, .7);
}

.fam-radio--plastic input:checked + .fam-radio-dot::after,
.fam-radio--metal input:checked + .fam-radio-dot::after {
  opacity: 1;
  transition-duration: .12s;
}

.fam-radio--glossy .fam-radio-dot {
  --fam-aqua-rim: #787c84;
  background: linear-gradient(to bottom, #fcfcfd 0%, #e4e6ea 52%, #c6cad1 100%);
  border: 1px solid var(--fam-aqua-rim);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .8), 0 2px 3px rgba(0, 0, 0, .4);
}

.fam-radio--glossy input:checked + .fam-radio-dot {
  --fam-aqua-rim: #2a4aa8;
  background: linear-gradient(to bottom, #3556c4 0%, #5a85ea 52%, #8db0f7 100%);
}

.fam-radio--glossy input:checked + .fam-radio-dot::after { background: #fff; box-shadow: 0 1px 1px rgba(0, 0, 40, .5); }

.fam-radio--glass {
  background: none;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
}

.fam-radio--glass .fam-radio-dot {
  --fam-glass-shade: rgba(0, 0, 0, .42);
  background:
    linear-gradient(to bottom, rgba(255, 255, 255, .3) 0%, rgba(255, 255, 255, .07) 46%, rgba(255, 255, 255, 0) 54%),
    linear-gradient(var(--fam-glass-shade), var(--fam-glass-shade));
  backdrop-filter: blur(6px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55), 0 3px 6px -2px rgba(0, 0, 0, .55);
}

/* The ink outline alone vanishes on dark felt, so the glass dot gets the white halo too */
.fam-radio--glass:has(input:focus-visible) .fam-radio-dot {
  box-shadow: var(--fam-focus-halo), inset 0 0 0 1px rgba(255, 255, 255, .55), 0 3px 6px -2px rgba(0, 0, 0, .55);
}

/* The checked dot turns blue like any active glass control */
.fam-radio--glass input:checked + .fam-radio-dot { --fam-glass-shade: var(--fam-glass-blue-shade); }

.fam-radio--glass input:checked + .fam-radio-dot::after { background: #fff; box-shadow: 0 0 4px rgba(255, 255, 255, .8); }

.fam-radio:has(input:disabled) { cursor: default; }

.fam-radio:has(input:disabled) .fam-radio-dot {
  box-shadow: inset 0 2px 3px rgba(0, 0, 0, .55);
}

.fam-radio--glass:has(input:disabled) .fam-radio-dot {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .55), inset 0 2px 3px rgba(0, 0, 0, .55);
}

/* Sunk into its case like a disabled plastic or metal button: a darker face and the same inset shadow */
.fam-radio--plastic:has(input:disabled) .fam-radio-dot,
.fam-radio--metal:has(input:disabled) .fam-radio-dot {
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, .6), inset 0 -1px 0 rgba(255, 255, 255, .18), 0 0 0 1px rgba(0, 0, 0, .45), 0 0 0 0 transparent, inset 0 0 0 11px rgba(0, 0, 0, .35);
}

@media (prefers-reduced-motion: reduce) {
  .fam-radio .fam-radio-dot,
  .fam-radio .fam-radio-dot::after,
  .fam-radio input:checked + .fam-radio-dot,
  .fam-radio input:checked + .fam-radio-dot::after { transition: none; }
}

/* ---------- LEDs: standalone indicator lamps for the plastic panel and the metal ----------
   The lens is a grayscale photo of a ringed panel lamp multiplied onto --fam-led-color, so one pair of images serves every color.
   The lit lens is the bright tinted glass with a glow; the unlit one is the same color as dark glass. The label is engraved by default
   and printed with fam-led-label--printed. The lens is decorative, so the state is carried by the text of fam-visually-hidden.
   The lit and unlit faces are custom properties because the plastic and metal radios and the button groups paint the same lens.
   A fam-led label that wraps a checkbox is a toggle, lit while checked, like fam-switch. */

.fam-led,
.fam-radio--plastic,
.fam-radio--metal,
.fam-button-group > :is(.fam-plastic, .fam-metal-button) {
  --fam-led-color: var(--fam-led);
  --fam-led-unlit-face:
    radial-gradient(circle at 34% 28%, rgba(255, 255, 255, .55), rgba(255, 255, 255, 0) 38%),
    var(--fam-tex-led-lens-unlit) center / 100% 100% no-repeat,
    color-mix(in srgb, var(--fam-led-color) 42%, #000);
  --fam-led-lit-face:
    radial-gradient(circle at 50% 46%, rgba(255, 246, 220, .85), rgba(255, 246, 220, 0) 42%),
    var(--fam-tex-led-lens-lit) center / 100% 100% no-repeat,
    var(--fam-led-color);
}

.fam-led {
  --fam-led-size: 28px;
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin: 2px 6px;
  padding: 4px 6px;
  border-radius: var(--fam-radius-sm);
  vertical-align: top;
}

.fam-led:has(input) { cursor: pointer; }

/* The native checkbox covers the whole LED, invisible but focusable and clickable */
.fam-led input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: inherit;
}

.fam-led:has(input:focus-visible) {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
  box-shadow: var(--fam-focus-halo);
}

.fam-led--green { --fam-led-color: #2fd24a; }
.fam-led--red { --fam-led-color: #ff2a2a; }
.fam-led--blue { --fam-led-color: #3a8bff; }
.fam-led--large { --fam-led-size: 44px; }

.fam-led-lens {
  box-sizing: border-box;
  position: relative;
  width: var(--fam-led-size);
  height: var(--fam-led-size);
  padding: 3px;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 35%, #3a3a3e, #0d0d10 80%);
  /* The bezel sits in a round well cut into the panel, like the one around a button group's cells: the lens casts a shadow into a darkened
     gutter, the well's edge is darker along the top, and a light lip catches the light along the bottom. The gutter reaches 5px out,
     which is why the label needs the 8px gap under the lens. */
  box-shadow:
    inset 0 2px 3px rgba(0, 0, 0, .7),
    0 2px 3px rgba(0, 0, 0, .45),
    0 0 0 1px rgba(0, 0, 0, .35),
    0 0 0 3px rgba(0, 0, 0, .16),
    0 -1px 0 4px rgba(0, 0, 0, .35),
    0 1px 0 4px rgba(255, 255, 255, .6);
}

.fam-led-lens::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: var(--fam-led-unlit-face);
  background-blend-mode: normal, multiply, normal;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12), inset 0 -2px 4px rgba(0, 0, 0, .5);
}

/* The lit lens is a layer over the unlit one, because a background image cannot fade into another. It fades out slowly like a cooling
   lamp and comes on quickly. */
.fam-led-lens::after {
  content: '';
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background: var(--fam-led-lit-face);
  background-blend-mode: normal, multiply, normal;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .25),
    0 0 5px 1px color-mix(in srgb, var(--fam-led-color) 80%, #fff),
    0 0 14px 4px color-mix(in srgb, var(--fam-led-color) 65%, transparent);
  opacity: 0;
  transition: opacity .5s ease-out;
}

.fam-led--lit .fam-led-lens::after,
.fam-led:has(input:checked) .fam-led-lens::after {
  opacity: 1;
  transition-duration: .12s;
}

/* 19px bold counts as large text (3:1), which is what the darkest brushed streaks allow behind a dark glyph, so the size is part of the class */
.fam-led:has(input:active:not(:disabled)) .fam-led-lens { transform: translateY(1px); }

/* Sunk into its case like a disabled plastic or metal button: no glow, a darker lens and the same fade */
.fam-led:has(input:disabled) {
  opacity: .7;
  cursor: default;
}

.fam-led:has(input:disabled) .fam-led-lens::before {
  box-shadow: inset 0 3px 5px rgba(0, 0, 0, .6), inset 0 -1px 0 rgba(255, 255, 255, .18), inset 0 0 0 var(--fam-led-size) rgba(0, 0, 0, .35);
}

.fam-led:has(input:disabled) .fam-led-lens::after {
  box-shadow: inset 0 0 0 var(--fam-led-size) rgba(0, 0, 0, .35);
}

.fam-led-label {
  font: 700 19px/1.1 var(--fam-font-ui);
  letter-spacing: .5px;
  text-transform: uppercase;
  color: rgb(18, 20, 26);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .9), 0 -1px 0 rgba(0, 0, 0, .2);
}

.fam-led-label--printed { text-shadow: none; }

@media (prefers-reduced-motion: reduce) {
  .fam-led-lens::after,
  .fam-led--lit .fam-led-lens::after,
  .fam-led:has(input:checked) .fam-led-lens::after { transition: none; }
}

.fam-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (forced-colors: active) {
  .fam-led-lens {
    border: 1px solid CanvasText;
    background: Canvas;
  }

  .fam-led-lens::before {
    background: Canvas;
    box-shadow: none;
  }

  .fam-led-lens::after { box-shadow: none; }

  .fam-led--lit .fam-led-lens::after,
  .fam-led:has(input:checked) .fam-led-lens::after { background: Highlight; }
}

/* ---------- Button groups: one case holding plastic, metal, glossy or leather buttons ----------
   Only the outer corners are rounded and neighbours overlap by one border, so the cells share a divider. A cell is lit by
   aria-pressed="true", or by aria-selected="true" when the group is a tab strip. The padding keeps the cells' shadows and focus
   rings inside the box, because a scrolling box clips whatever pokes out of it. */

.fam-button-group {
  box-sizing: border-box;
  display: inline-flex;
  max-width: 100%;
  padding: 5px 5px 8px;
  overflow-x: auto;
  vertical-align: middle;
}

/* Plastic and metal cells sit in a well cut into the surface: the material darkened, an inset edge and a light lip below.
   The 6px of padding is also what keeps the cells' shadows and focus rings inside the scrolling box. */
.fam-button-group:not(.fam-button-group--case):has(> :is(.fam-plastic, .fam-metal-button)) {
  padding: 6px;
  border-radius: var(--fam-radius-pill);
  background: linear-gradient(rgba(0, 0, 0, .3), rgba(0, 0, 0, .14));
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, .5), inset 0 0 0 1px rgba(0, 0, 0, .35), 0 1px 0 rgba(255, 255, 255, .5);
}

.fam-button-group:not(.fam-button-group--case):has(> :is(.fam-plastic--square, .fam-metal-button--square)) {
  border-radius: calc(var(--fam-radius-md) + 6px);
}

.fam-button-group > .fam-plastic { --fam-ring: 0 0 0 0 transparent; }

.fam-button-group > * {
  --fam-cell-radius: var(--fam-radius-pill);
  position: relative;
  flex: none;
  margin: 0;
  border-radius: 0;
  transition: box-shadow .15s ease;
}

.fam-button-group > .fam-plastic--square,
.fam-button-group > .fam-metal-button--square { --fam-cell-radius: var(--fam-radius-md); }

.fam-button-group > .fam-leather-button {
  width: auto;
  margin-top: 0;
}

.fam-button-group > * + * { margin-left: -1px; }

/* Neighbours overlap by a border, so the focused cell has to paint above them or the next cell cuts its ring */
.fam-button-group > :focus-visible { z-index: 1; }

.fam-button-group > :first-child {
  border-top-left-radius: var(--fam-cell-radius);
  border-bottom-left-radius: var(--fam-cell-radius);
}

.fam-button-group > :last-child {
  border-top-right-radius: var(--fam-cell-radius);
  border-bottom-right-radius: var(--fam-cell-radius);
}

/* A cell that can be lit holds two lenses: the unlit one is its ::before and the lit one its ::after, which fades in over it. In the dish of a
   round or square plastic cell they replace the cell's faint sheen. */
.fam-button-group > :is(.fam-plastic--round, .fam-plastic--square):is([aria-pressed], [aria-selected])::before {
  inset: 5px;
  z-index: -1;
  border-radius: 50%;
  background: var(--fam-led-unlit-face);
  background-blend-mode: normal, multiply, normal;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12), inset 0 -1px 2px rgba(0, 0, 0, .5), 0 1px 0 rgba(255, 255, 255, .35);
}

.fam-button-group > :is(.fam-plastic--round, .fam-plastic--square):is([aria-pressed], [aria-selected])::after {
  background: var(--fam-led-lit-face);
  background-blend-mode: normal, multiply, normal;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .25), 0 0 6px 1px #ffb273, 0 0 10px 2px rgba(255, 106, 31, .5);
  opacity: 0;
  transition: opacity .5s ease-out;
}

.fam-button-group > :is(.fam-plastic--round, .fam-plastic--square):is([aria-pressed="true"], [aria-selected="true"])::after {
  opacity: 1;
  transition-duration: .12s;
}

/* A lit plastic or metal cell is pressed in: no outer shadow, only the inset one, like the pocket of the current nav item */
.fam-button-group > :is(.fam-plastic, .fam-metal-button):is([aria-pressed="true"], [aria-selected="true"]) {
  --fam-rest-shadow: inset 0 3px 5px rgba(0, 0, 0, .55), inset 0 -1px 0 rgba(255, 255, 255, .2);
}

/* Labeled plastic cells and every metal cell have no dish, so the two lenses are small dots above the label */
.fam-button-group > :is(.fam-plastic:not(.fam-plastic--round, .fam-plastic--square), .fam-metal-button):is([aria-pressed], [aria-selected])::before,
.fam-button-group > :is(.fam-plastic:not(.fam-plastic--round, .fam-plastic--square), .fam-metal-button):is([aria-pressed], [aria-selected])::after {
  content: '';
  position: absolute;
  inset: 2px auto auto 50%;
  width: 5px;
  height: 5px;
  margin-left: -2.5px;
  border-radius: 50%;
  pointer-events: none;
}

.fam-button-group > :is(.fam-plastic:not(.fam-plastic--round, .fam-plastic--square), .fam-metal-button):is([aria-pressed], [aria-selected])::before {
  background: var(--fam-led-unlit-face);
  background-blend-mode: normal, multiply, normal;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .45), 0 1px 0 rgba(255, 255, 255, .5);
}

.fam-button-group > :is(.fam-plastic:not(.fam-plastic--round, .fam-plastic--square), .fam-metal-button):is([aria-pressed], [aria-selected])::after {
  background: var(--fam-led-lit-face);
  background-blend-mode: normal, multiply, normal;
  box-shadow: 0 0 4px 1px #ffb273, 0 0 9px 3px rgba(255, 106, 31, .7);
  opacity: 0;
  transition: opacity .5s ease-out;
}

.fam-button-group > :is(.fam-plastic:not(.fam-plastic--round, .fam-plastic--square), .fam-metal-button):is([aria-pressed="true"], [aria-selected="true"])::after {
  opacity: 1;
  transition-duration: .12s;
}

.fam-button-group > .fam-glossy-button:is([aria-pressed="true"], [aria-selected="true"]) {
  --fam-rest-shadow: inset 0 2px 5px rgba(0, 0, 0, .4), 0 1px 0 rgba(255, 255, 255, .5);
}

/* The selected segment of a silver strip turns aqua, as in references/snow-leopard-gui-2079776605.png */
.fam-button-group > .fam-glossy-button--silver:is([aria-pressed="true"], [aria-selected="true"]) {
  --fam-aqua-rim: #2a4aa8;
  --fam-aqua-top: #6a98f2;
  --fam-aqua-mid: #86acf7;
  --fam-aqua-bottom: #bcd3fb;
  color: rgb(8, 20, 60);
}

/* A leather group is a pill of the nav bar's leather holding flat items, and the lit item is cut as the same dark pocket the nav
   bar uses for the current page. Its cells have no raised button face of their own. */
.fam-button-group--leather {
  gap: 4px;
  padding: 6px;
  border-radius: var(--fam-radius-pill);
  background: var(--fam-tex-leather-fill-tan-tile) 0 0 / 168px 51.5px repeat;
  box-shadow: 0 0 0 1px rgba(60, 30, 8, .55), inset 0 1px 0 rgba(255, 244, 220, .75), 0 3px 7px rgba(50, 25, 5, .5);
}

.fam-button-group--leather > .fam-leather-button {
  padding: 7px 18px;
  border: 0;
  border-radius: var(--fam-radius-pill);
  background: none;
  box-shadow: none;
  color: #000;
  font: 600 14px/1.2 var(--fam-font-ui);
  letter-spacing: .3px;
  text-shadow: 0 1px 0 rgba(255, 238, 205, .6), 0 -1px 0 rgba(60, 30, 5, .3);
  margin-left: 0;
}

.fam-button-group--leather > .fam-leather-button:is([aria-pressed="true"], [aria-selected="true"]) {
  background: linear-gradient(rgba(30, 14, 3, .85), rgba(30, 14, 3, .65));
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .7), 0 1px 0 rgba(255, 238, 205, .6);
  color: #ece3cf;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .8);
}

/* A padded case around separate cells, like the grouped strip in references/plastic.png */
.fam-button-group--case {
  gap: 3px;
  padding: 5px;
  border-radius: var(--fam-radius-md);
  background:
    var(--fam-tex-grain-plastic) 0 0 / 128px 128px,
    linear-gradient(to bottom, #f1ebd9, #d8cfb5);
  background-blend-mode: soft-light, normal;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .65), 0 2px 4px rgba(0, 0, 0, .4), inset 0 1px 0 rgba(255, 255, 255, .9);
}

.fam-button-group--case > .fam-plastic,
.fam-button-group--case > .fam-metal-button,
.fam-button-group--case > .fam-glossy-button {
  margin-left: 0;
  border-radius: 8px;
}

@media (prefers-reduced-motion: reduce) {
  .fam-button-group > * { transition: none; }

  .fam-button-group > :is(.fam-plastic, .fam-metal-button):is([aria-pressed], [aria-selected])::after,
  .fam-button-group > :is(.fam-plastic, .fam-metal-button):is([aria-pressed="true"], [aria-selected="true"])::after,
  .fam-button-group > :is(.fam-plastic:not(.fam-plastic--round, .fam-plastic--square), .fam-metal-button):is([aria-pressed], [aria-selected])::after,
  .fam-button-group > :is(.fam-plastic:not(.fam-plastic--round, .fam-plastic--square), .fam-metal-button):is([aria-pressed="true"], [aria-selected="true"])::after { transition: none; }
}

/* Plastic dial drawn in CSS like the ridged knob and the cream dial in references/plastic.png: a ridged rim, a dished cream face
   and an orange tick that --fam-knob-angle turns. It is a picture, like .fam-knob, so give it role="img" and say its value in the label. */
.fam-dial {
  --fam-knob-angle: 35deg;
  box-sizing: border-box;
  position: relative;
  display: inline-block;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background:
    var(--fam-tex-grain-fine) 0 0 / 128px 128px,
    repeating-conic-gradient(rgba(0, 0, 0, .3) 0 2deg, rgba(255, 255, 255, .22) 2deg 4deg),
    linear-gradient(to bottom, #c4bfb0, #8f8a7a);
  background-blend-mode: soft-light, normal, normal;
  box-shadow: inset 0 0 0 2px rgba(0, 0, 0, .3), 0 5px 9px rgba(0, 0, 0, .45), 0 0 0 1px rgba(0, 0, 0, .6), var(--fam-elevation, 0 0 0 0 transparent);
}

.fam-dial::before {
  content: '';
  position: absolute;
  inset: 9px;
  border-radius: 50%;
  background:
    var(--fam-tex-grain-plastic) 0 0 / 128px 128px,
    radial-gradient(circle at 50% 30%, #f6f1e0, #d6cdb2 70%, #b9af94);
  background-blend-mode: soft-light, normal;
  box-shadow: inset 0 2px 3px rgba(255, 255, 255, .9), inset 0 -3px 5px rgba(0, 0, 0, .25), 0 1px 2px rgba(0, 0, 0, .5);
}

.fam-dial::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 13px;
  width: 4px;
  height: 16px;
  margin-left: -2px;
  border-radius: 2px;
  background: var(--fam-led);
  box-shadow: 0 0 5px rgba(255, 106, 31, .7), 0 1px 0 rgba(255, 255, 255, .4);
  transform-origin: 50% 23px;
  transform: rotate(var(--fam-knob-angle));
}

/* Face built from the spiral photo: clean rings with the photo's own bright and dark wedges baked in, so it reflects light like spun metal.
   The reflections are part of the image, so they stay put while --fam-knob-angle turns the orange indicator. */
.fam-knob {
  --fam-knob-angle: 35deg;
  box-sizing: border-box;
  position: relative;
  display: inline-block;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 14%, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0) 55%),
    var(--fam-tex-knob-face) 0 0 / 100% 100%;
  box-shadow: inset 0 -3px 6px rgba(0, 0, 0, .4), inset 0 1px 1px rgba(255, 255, 255, .8), 0 5px 9px rgba(0, 0, 0, .55), 0 0 0 1px rgba(0, 0, 0, .6), var(--fam-elevation, 0 0 0 0 transparent);
}

.fam-knob::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  box-shadow: inset 0 0 0 3px rgba(215, 219, 227, .5), inset 0 0 0 4px rgba(0, 0, 0, .3);
}

.fam-knob::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 11px;
  width: 4px;
  height: 14px;
  margin-left: -2px;
  border-radius: 2px;
  background: #e8561c;
  box-shadow: 0 0 5px rgba(255, 120, 40, .8), 0 1px 0 rgba(255, 255, 255, .4);
  transform-origin: 50% 25px;
  transform: rotate(var(--fam-knob-angle));
}

/* ---------- Text fields and the leather button ----------
   A field is a well cut into whatever it sits on. The fill is part white so the material's texture shows through, and the
   shadows are neutral so the field reads on wood, leather, linen, metal, paper and chalkboard alike. */

.fam-field {
  --fam-field-pad-y: 11px;
  --fam-field-pad-x: 14px;
  --fam-field-size: 15px;
  --fam-field-inset: inset 0 2px 5px rgba(0, 0, 0, .4), inset 0 0 0 1px rgba(0, 0, 0, .4);
  --fam-field-lip: 0 1px 0 rgba(255, 255, 255, .45);
  --fam-field-halo: 0 0 0 0 transparent;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: var(--fam-field-pad-y) var(--fam-field-pad-x);
  border-radius: var(--fam-radius-md);
  background: linear-gradient(rgba(255, 255, 255, .5), rgba(255, 255, 255, .38));
  box-shadow: var(--fam-field-inset), var(--fam-field-lip), var(--fam-field-halo);
  color: #17171a;
  font-size: var(--fam-field-size);
}

.fam-field input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  font: inherit;
  color: inherit;
}

.fam-field input::placeholder { color: #000; }

.fam-field svg {
  flex: none;
  color: rgba(0, 0, 0, .62);
}

/* The pill keeps the opaque gray-white it always had */
.fam-field--pill {
  --fam-field-inset: inset 0 2px 4px rgba(0, 0, 0, .3), inset 0 0 0 1px rgba(0, 0, 0, .28);
  --fam-field-lip: 0 1px 0 rgba(255, 255, 255, .9);
  border-radius: var(--fam-radius-pill);
  background: linear-gradient(#e9e9ec, #f6f6f8);
  color: #25252a;
}

.fam-field--pill input::placeholder { color: rgb(100, 100, 108); }

.fam-field--sm {
  --fam-field-pad-y: 6px;
  --fam-field-pad-x: 11px;
  --fam-field-size: 13px;
}

.fam-field--lg {
  --fam-field-pad-y: 15px;
  --fam-field-pad-x: 18px;
  --fam-field-size: 18px;
}

/* iOS Safari zooms the page when a field under 16px gets focus. max() leaves the large field at its 18px. */
@media (pointer: coarse) {
  .fam-field { font-size: max(var(--fam-field-size), 16px); }
}

/* Labeled rows share one well, like the sign-in card. The padding moves from the field to its rows. */
.fam-field--group {
  display: block;
  padding: 0;
  overflow: hidden;
}

.fam-field-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: calc(var(--fam-field-pad-y) + 1px) calc(var(--fam-field-pad-x) + 2px);
}

.fam-field-row + .fam-field-row { border-top: 1px solid rgba(0, 0, 0, .25); }

.fam-field-row label {
  flex: 0 0 82px;
  font-weight: 700;
  font-size: .87em;
}

/* Beside an 82px label, the input in a leather-framed card is about 120px wide, which cuts an email address, so the label column narrows to fit "Password" */
@media (max-width: 480px) {
  .fam-field-row {
    gap: 8px;
    padding-inline: var(--fam-field-pad-x);
  }

  .fam-field-row label { flex-basis: 64px; }
}

.fam-field:focus-within {
  --fam-field-halo: var(--fam-focus-halo);
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
}

/* Invalid is set with aria-invalid on the input. The shake plays as the attribute appears, so clear it and set it again to
   shake on a second failed attempt. A grouped field turns red as a whole. */
.fam-field:has(input[aria-invalid="true"]) {
  --fam-field-inset: inset 0 2px 5px rgba(0, 0, 0, .4), inset 0 0 0 2px #c4281c;
  animation: fam-field-shake .45s cubic-bezier(.36, .07, .19, .97);
}

.fam-field--pill:has(input[aria-invalid="true"]) {
  --fam-field-inset: inset 0 2px 4px rgba(0, 0, 0, .3), inset 0 0 0 2px #c4281c;
}

@keyframes fam-field-shake {
  15% { transform: translateX(-7px); }
  30% { transform: translateX(6px); }
  45% { transform: translateX(-5px); }
  60% { transform: translateX(4px); }
  75% { transform: translateX(-2px); }
  90% { transform: translateX(1px); }
}

@media (prefers-reduced-motion: reduce) {
  .fam-field:has(input[aria-invalid="true"]) { animation: none; }
}

/* The message goes under the field and is linked to the input with aria-describedby. It is a light chip so it reads on any material. */
.fam-field-message {
  display: block;
  width: fit-content;
  max-width: 100%;
  box-sizing: border-box;
  margin-top: 8px;
  padding: 3px 10px;
  border-radius: var(--fam-radius-pill);
  background: rgba(255, 244, 242, .95);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
  color: #9c1c12;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
}

.fam-leather-button {
  box-sizing: border-box;
  display: block;
  width: 100%;
  margin-top: 16px;
  padding: 12px 16px;
  border-radius: 10px;
  cursor: pointer;
  font: 700 15px/1 var(--fam-font-ui);
  color: #3a1f08;
  text-shadow: 0 1px 0 rgba(255, 225, 170, .6);
  border: 1px solid #6e431b;
  background: linear-gradient(#dcaa6c, #be8647);
  box-shadow: inset 0 1px 0 rgba(255, 235, 190, .75), inset 0 -2px 3px rgba(80, 40, 5, .25), 0 1px 0 rgba(255, 255, 255, .3), 0 3px 5px rgba(0, 0, 0, .35);
}

.fam-leather-button:active:not(:disabled) { box-shadow: inset 0 2px 4px rgba(80, 40, 5, .45), 0 1px 0 rgba(255, 255, 255, .3); }

.fam-leather-button:focus-visible {
  outline: 3px solid #3a1f08;
  outline-offset: 2px;
}

/* ---------- Wooden navigation bar. Use with .fam-wood for the surface. ---------- */

.fam-nav {
  box-sizing: border-box;
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 54px;
  padding: 0 14px;
  /* Scrolls inside itself when its items do not fit, instead of spilling past the wood */
  overflow-x: auto;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .4), inset 0 -2px 6px rgba(80, 40, 10, .45), 0 4px 10px rgba(0, 0, 0, .5);
}

/* Dark engraved text on light wood: a dark glyph with a light lip along the lower edge */
.fam-nav-brand {
  margin-right: 14px;
  white-space: nowrap;
  font-weight: 700;
  letter-spacing: .5px;
  color: #1c0d03;
  text-shadow: 0 1px 0 rgba(255, 238, 205, .6), 0 -1px 0 rgba(60, 30, 5, .3);
}

/* Labels keep their natural width; only a pathologically long one is cut with an ellipsis */
.fam-nav-item {
  flex: 0 0 auto;
  max-width: 14em;
  padding: 7px 18px;
  border-radius: var(--fam-radius-pill);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-decoration: none;
  font-weight: 600;
  letter-spacing: .3px;
  color: #1c0d03;
  text-shadow: 0 1px 0 rgba(255, 238, 205, .6), 0 -1px 0 rgba(60, 30, 5, .3);
}

/* Only the active item is recessed: a pocket cut into the wood, shadowed along the top edge with a light lip along the bottom */
.fam-nav-item[aria-current="page"] {
  background: linear-gradient(rgba(60, 30, 5, .16), rgba(60, 30, 5, .06));
  box-shadow: inset 0 2px 4px rgba(50, 25, 5, .5), inset 0 0 0 1px rgba(50, 25, 5, .35), 0 1px 0 rgba(255, 238, 205, .6);
}

.fam-nav-item:focus-visible {
  outline: 3px solid #1c0d03;
  outline-offset: 1px;
}

/* A wood group is a pill of the wooden navigation bar's wood (put fam-wood on it) holding fam-nav-item buttons, and the selected
   tab is cut as the same pocket the bar uses for the current page. */
.fam-button-group--wood {
  gap: 4px;
  padding: 6px;
  border-radius: var(--fam-radius-pill);
  box-shadow: 0 0 0 1px rgba(60, 30, 8, .5), inset 0 1px 0 rgba(255, 255, 255, .4), inset 0 -2px 6px rgba(80, 40, 10, .45), 0 3px 7px rgba(50, 25, 5, .5);
}

.fam-button-group--wood > .fam-nav-item {
  margin-left: 0;
  border: 0;
  border-radius: var(--fam-radius-pill);
  background: none;
  font: 600 14px/1.2 var(--fam-font-ui);
  cursor: pointer;
}

.fam-button-group--wood > .fam-nav-item:is([aria-pressed="true"], [aria-selected="true"]) {
  background: linear-gradient(rgba(60, 30, 5, .16), rgba(60, 30, 5, .06));
  box-shadow: inset 0 2px 4px rgba(50, 25, 5, .5), inset 0 0 0 1px rgba(50, 25, 5, .35), 0 1px 0 rgba(255, 238, 205, .6);
}

/* Metal, paper and cardstock bars: the engraved metal ink and a neutral shadow in place of the wood nav's brown.
   The first inset layer is a full-bar white overlay, which lifts the darkest patches of the photo so the ink reaches contrast. */
.fam-nav:is(.fam-metal-brushed, .fam-metal, .fam-paper, .fam-cardstock) {
  box-shadow: inset 0 0 0 999px rgba(255, 255, 255, .2), inset 0 1px 0 rgba(255, 255, 255, .7), inset 0 -2px 6px rgba(0, 0, 0, .25), 0 4px 10px rgba(0, 0, 0, .5);
}

.fam-nav:is(.fam-metal-brushed, .fam-metal, .fam-paper, .fam-cardstock) .fam-nav-brand,
.fam-nav:is(.fam-metal-brushed, .fam-metal, .fam-paper, .fam-cardstock) .fam-nav-item {
  color: rgb(18, 20, 26);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .9), 0 -1px 0 rgba(0, 0, 0, .2);
}

/* Dark enough that the label flips to light text, as on the leather bar; the dark ink would lose contrast on a darker pocket */
.fam-nav:is(.fam-metal-brushed, .fam-metal, .fam-paper, .fam-cardstock) .fam-nav-item[aria-current="page"] {
  background: linear-gradient(rgba(14, 16, 22, .82), rgba(14, 16, 22, .6));
  box-shadow: inset 0 3px 6px rgba(0, 0, 0, .8), inset 0 0 0 1px rgba(0, 0, 0, .55), 0 1px 0 rgba(255, 255, 255, .8);
  color: #eceae4;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .8);
}

.fam-nav:is(.fam-metal-brushed, .fam-metal, .fam-paper, .fam-cardstock) .fam-nav-item:focus-visible { outline-color: rgb(18, 20, 26); }

/* Leather bar: tan keeps the frame's own tone, so its text is black.
   Black and brown leather and the dark paneled wood flip to light text with a dark lip. All of them cut the active item as a dark pocket with light text. */
.fam-nav.fam-leather-bar {
  padding-bottom: 8px;
  box-shadow: inset 0 1px 0 rgba(255, 244, 220, .75), 0 3px 7px rgba(50, 25, 5, .5);
}

.fam-leather-bar .fam-nav-brand,
.fam-leather-bar .fam-nav-item { color: #000; }

/* Dark enough that the label flips to light text, as on the black bar; black text on a darkened tan fell under 4.5:1 */
.fam-leather-bar .fam-nav-item[aria-current="page"] {
  background: linear-gradient(rgba(30, 14, 3, .85), rgba(30, 14, 3, .65));
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .7), 0 1px 0 rgba(255, 238, 205, .6);
  color: #ece3cf;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .8);
}

.fam-nav:is(.fam-leather-bar--black, .fam-leather-bar--brown, .fam-wood-paneled) {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .22), 0 4px 9px rgba(0, 0, 0, .6);
}

/* The walnut is a mid brown, so the light ink needs a darker bar behind it than the leathers do */
.fam-nav.fam-wood-paneled {
  box-shadow: inset 0 0 0 999px rgba(0, 0, 0, .35), inset 0 1px 0 rgba(255, 255, 255, .22), 0 4px 9px rgba(0, 0, 0, .6);
}

:is(.fam-leather-bar--black, .fam-leather-bar--brown, .fam-wood-paneled) .fam-nav-brand,
:is(.fam-leather-bar--black, .fam-leather-bar--brown, .fam-wood-paneled) .fam-nav-item {
  color: #ece3cf;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .8);
}

:is(.fam-leather-bar--black, .fam-leather-bar--brown, .fam-wood-paneled) .fam-nav-item[aria-current="page"] {
  background: linear-gradient(rgba(0, 0, 0, .55), rgba(0, 0, 0, .25));
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, .85), 0 1px 0 rgba(255, 255, 255, .18);
}

:is(.fam-leather-bar--black, .fam-leather-bar--brown, .fam-wood-paneled) .fam-nav-item:focus-visible { outline-color: #ece3cf; }

/* Four short labels and the brand are about 380px wide at full size, which does not fit a 375px phone with the page gutters */
@media (max-width: 480px) {
  .fam-nav {
    gap: 2px;
    padding: 0 6px;
  }

  .fam-nav-brand {
    margin-right: 6px;
    font-size: 13px;
  }

  .fam-nav-item {
    padding: 7px 5px;
    font-size: 13px;
    letter-spacing: 0;
  }
}

/* ---------- List rows ---------- */

.fam-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A row is a real link or button inside a plain list; mark the current one with aria-current="true" (aria-selected="true" also works for rows you make into a listbox) */
.fam-list-row {
  box-sizing: border-box;
  text-decoration: none;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 11px 16px;
  border-top: 1px solid rgba(0, 0, 0, .13);
  font-family: var(--fam-font-hand);
  color: #2a241a;
}

.fam-list-row b {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 15px;
  font-weight: 700;
}

.fam-list-row span {
  flex: none;
  font: 12px/1 var(--fam-font-ui);
  color: #5a5a61;
}

.fam-list-row[aria-current="true"],
.fam-list-row[aria-selected="true"] {
  color: #fff;
  text-shadow: 0 -1px 0 rgba(0, 30, 110, .8);
  background: linear-gradient(to bottom, var(--fam-blue-top), var(--fam-blue-bottom));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3);
  border-top-color: #1148b0;
}

.fam-list-row[aria-current="true"] span,
.fam-list-row[aria-selected="true"] span { color: rgba(255, 255, 255, .92); }

.fam-list-row:focus-visible {
  outline: 2px solid #1b1b20;
  outline-offset: -4px;
}

.fam-list-row[aria-current="true"]:focus-visible,
.fam-list-row[aria-selected="true"]:focus-visible { outline-color: #fff; }

/* ---------- Zebra table ----------
   The box draws every stripe once, in a gradient that scrolls with its content, and the rows are transparent. The real rows and the
   empty stripes below them are therefore the same gradient and cannot drift apart, as long as every row is one row high. The stripes
   and dividers are a see-through tint of one ink, so the material behind the box shows through. The sticky header is opaque instead,
   because rows scrolling under a see-through header would show through it. */

.fam-table-box {
  --fam-table-ink-default: rgb(60, 40, 10);
  --fam-table-text-default: #1d1d21;
  --fam-table-head-text-default: #2e2415;
  --fam-table-header-default: #e4dccb;
  --fam-table-focus-default: #1b1b20;
  --fam-table-row: var(--fam-row-height, 24px);
  --fam-table-ink-color: var(--fam-table-ink, var(--fam-table-ink-default));
  box-sizing: content-box;
  height: calc(var(--fam-table-row) * (var(--fam-table-rows, 8) + 1));
  overflow: auto;
  scroll-padding-top: var(--fam-table-row);
  border-radius: 4px;
  background-image: repeating-linear-gradient(to bottom, transparent 0 var(--fam-table-row), color-mix(in srgb, var(--fam-table-ink-color) calc(var(--fam-table-stripe, .09) * 100%), transparent) var(--fam-table-row) calc(var(--fam-table-row) * 2));
  background-size: 100% calc(var(--fam-table-row) * 2);
  background-position: 0 var(--fam-table-row);
  background-repeat: repeat-y;
  background-attachment: local;
  --fam-table-edge: inset 0 0 0 1px color-mix(in srgb, var(--fam-table-ink-color) 40%, transparent), inset 0 2px 4px rgba(0, 0, 0, .18), 0 1px 0 rgba(255, 255, 255, .7);
  box-shadow: var(--fam-table-edge);
}

/* For dark materials such as brown cardstock: a light ink, light text, a dark header and a light focus ring. Most of the kit's leather and wood
   are washed light so that dark text reads on them, so those take the dark ink. */
.fam-table-box--light-ink {
  --fam-table-ink-default: rgb(255, 235, 200);
  --fam-table-text-default: #f6ecd8;
  --fam-table-head-text-default: #f6ecd8;
  --fam-table-header-default: #3a2412;
  --fam-table-focus-default: #fff;
}

.fam-table-box:focus-visible {
  outline: 2px solid var(--fam-focus-ink);
  outline-offset: 2px;
  box-shadow: var(--fam-focus-halo), var(--fam-table-edge);
}

.fam-table {
  width: 100%;
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
  font: 12px/1 var(--fam-font-ui);
  color: var(--fam-table-text-default);
}

.fam-table th,
.fam-table td {
  box-sizing: border-box;
  height: var(--fam-table-row);
  padding: 0 8px;
  overflow: hidden;
  text-align: left;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Only the header cells are divided, as in Snow Leopard's lists; the body columns have no lines */
.fam-table thead th + th { border-left: 1px solid color-mix(in srgb, var(--fam-table-ink-color) 22%, transparent); }

/* A caption would sit inside the scroll box above the header and push every row off its stripe, so it is read by screen readers only */
.fam-table > caption {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.fam-table th { font-weight: 400; }

.fam-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  color: var(--fam-table-head-text-default);
  background: var(--fam-table-header, var(--fam-table-header-default));
  border-bottom: 1px solid color-mix(in srgb, var(--fam-table-ink-color) 45%, transparent);
}

/* A selectable table is role="grid" and marks its chosen row with aria-selected="true", in the blue of a selected list row */
.fam-table tr[aria-selected="true"] > * {
  color: #fff;
  text-shadow: 0 -1px 0 rgba(0, 30, 110, .8);
  background: linear-gradient(to bottom, var(--fam-blue-top), var(--fam-blue-bottom));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .3);
}

.fam-table tbody tr:focus-visible {
  outline: 2px solid var(--fam-table-focus-default);
  outline-offset: -2px;
}

.fam-table tr[aria-selected="true"]:focus-visible { outline-color: #fff; }

/* ---------- Disabled controls: dimmed, no pointer cursor, no pressed look (disabled text is exempt from WCAG contrast) ---------- */

.fam-leather-button:disabled,
.fam-nav-item:disabled,
.fam-radio:has(input:disabled),
.fam-glossy-button:disabled,
.fam-glass-button:disabled,
.fam-switch:has(input:disabled),
.fam-glass:has(.fam-glass-input:disabled),
.fam-field:has(input:disabled) {
  opacity: .5;
  cursor: default;
}

.fam-switch input:disabled,
.fam-glass-input:disabled,
.fam-field input:disabled { cursor: default; }

/* Plastic and metal radios fade only as much as the plastic and metal buttons do */
.fam-radio--plastic:has(input:disabled),
.fam-radio--metal:has(input:disabled) { opacity: .7; }

/* ---------- Forced colors (Windows high contrast) ----------
   The mode replaces authored colors and drops box-shadows and gradients, so state and focus are carried by system colors,
   borders, outlines and underlines instead. A transparent outline is drawn in a system color in this mode. */
@media (forced-colors: active) {
  .fam-progress { border: 1px solid CanvasText; }

  .fam-progress-fill {
    background: Highlight;
    box-shadow: none;
  }

  .fam-menu > [aria-selected="true"],
  .fam-list-row[aria-current="true"],
  .fam-list-row[aria-selected="true"] {
    background: Highlight;
    color: HighlightText;
    text-shadow: none;
  }

  .fam-list-row[aria-current="true"] span,
  .fam-list-row[aria-selected="true"] span { color: HighlightText; }

  .fam-nav-item[aria-current="page"] { text-decoration: underline; }

  .fam-table-box { border: 1px solid CanvasText; }
  .fam-table thead th { border-bottom: 1px solid CanvasText; }
  .fam-table thead th + th { border-left-color: CanvasText; }

  .fam-table tr[aria-selected="true"] > * {
    background: Highlight;
    color: HighlightText;
    text-shadow: none;
  }

  .fam-switch { border: 1px solid CanvasText; }
  .fam-switch:has(input:checked) { background: Highlight; }

  .fam-button-group > [aria-pressed="true"],
  .fam-button-group > [aria-selected="true"] {
    outline: 2px solid Highlight;
    outline-offset: -4px;
    text-decoration: underline;
  }

  /* One outline cannot be both marker and ring, so a focused selected cell moves its outline out to the usual ring and keeps the underline as the marker */
  .fam-button-group > [aria-pressed="true"]:focus-visible,
  .fam-button-group > [aria-selected="true"]:focus-visible { outline-offset: 2px; }

  .fam-radio-dot { border: 1px solid CanvasText; }
  .fam-radio input:checked + .fam-radio-dot::after { background: Highlight; }

  .fam-field { border: 1px solid CanvasText; }
  .fam-field:has(input[aria-invalid="true"]) { border: 2px solid Mark; }

  .fam-glass:has(.fam-glass-input:focus-visible),
  .fam-field:focus-within {
    outline: 2px solid transparent;
    outline-offset: 2px;
  }
}

/* fam-ui templates */

/* ---------- Felt controls screen. Use with .fam-felt. ---------- */

.fam-screen {
  min-height: 560px;
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, .55), 0 0 0 1px rgba(0, 0, 0, .6);
}

.fam-screen-body {
  box-sizing: border-box;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 26px 34px;
  padding: 28px;
}

.fam-screen-label {
  margin-bottom: 8px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .8px;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
}

.fam-switch-row {
  display: flex;
  align-items: center;
  gap: 22px;
}

.fam-switch-label {
  font-size: 12px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);
}

.fam-swatch-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 4px;
}

/* Use with .fam-felt and set --fam-tint inline */
.fam-swatch {
  width: 86px;
  height: 56px;
  border-radius: 10px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .6), 0 6px 12px -4px rgba(0, 0, 0, .5);
}

.fam-swatch-caption {
  margin-top: 4px;
  font-size: 11px;
  text-align: center;
  color: #c9c9d0;
}

/* ---------- Notes app, after the iOS 4 Notes reference. Use .fam-notes with .fam-leather-frame and .fam-leather-frame--black. ---------- */

/* The frame is a size container so the layout follows the room the notes actually have, not the viewport */
.fam-notes {
  padding: 8px;
  container-type: inline-size;
}

/* One column by default: the list above the pad, both full width */
.fam-notes-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 12px;
}

/* 300px list + 12px gap + a pad of at least 420px */
@container (min-width: 732px) {
  .fam-notes-split { grid-template-columns: 300px minmax(0, 1fr); }
}

/* Use with .fam-paper */
.fam-notes-list {
  position: relative;
  min-width: 0;
  min-height: 560px;
  border-radius: 6px;
  overflow: hidden;
  color: #2a241a;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .6), 0 6px 14px -4px rgba(0, 0, 0, .6);
}

.fam-notes-heading {
  margin: 0;
  padding: 14px 0 10px;
  text-align: center;
  font-size: 17px;
}

.fam-notes-list .fam-field { margin: 0 14px 12px; }

.fam-pad {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, .6), 0 6px 14px -4px rgba(0, 0, 0, .6);
}

/* Use with .fam-cardstock: the cardstock is tinted brown so the white title text keeps its contrast */
.fam-pad-bar {
  --fam-cardstock-tint: #562a0e;
  position: relative;
  z-index: 1;
  display: grid;
  flex: none;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: 46px;
  padding: 0 12px;
  box-shadow: inset 0 1px 0 rgba(255, 220, 170, .35), 0 3px 6px rgba(0, 0, 0, .5);
}

.fam-pad-title {
  grid-column: 2;
  margin: 0;
  font-size: 17px;
  color: #fff;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .7);
}

.fam-pad-add {
  grid-column: 3;
  justify-self: end;
  display: grid;
  place-items: center;
  width: 34px;
  height: 26px;
  border-radius: 6px;
  cursor: pointer;
  font: 700 18px/1 var(--fam-font-ui);
  color: #fff;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, .6);
  border: 1px solid #2d1707;
  background: linear-gradient(#9a6a40, #664020);
  box-shadow: inset 0 1px 0 rgba(255, 225, 185, .5), 0 1px 0 rgba(255, 225, 170, .25);
}

.fam-pad-add:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 2px;
}

/* Use with .fam-legal-pad. The 24px line height lines text up with the pad's rules. */
.fam-pad-sheet {
  position: relative;
  flex: 1;
  box-sizing: border-box;
  min-height: 500px;
  padding: 0 18px 64px 52px;
  font: 19px/24px var(--fam-font-hand);
  color: #2b2216;
}

.fam-pad-meta {
  display: flex;
  justify-content: space-between;
  font: 600 12px/24px var(--fam-font-ui);
  color: #82301c;
}

.fam-pad-sheet p {
  margin: 0;
  white-space: pre-line;
}

/* A plain strip under the icons keeps them at contrast over the ruled lines */
.fam-pad-tools {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  gap: 44px;
  padding: 22px 0 14px;
  color: #82301c;
  background: linear-gradient(rgba(251, 238, 156, 0), #fbee9c 38%);
}

/* Four 34px icons with 44px gaps are 268px wide, wider than the pad on a 375px phone */
@media (max-width: 480px) {
  .fam-pad-tools { gap: 24px; }
}

.fam-pad-tools button {
  padding: 4px;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}

.fam-pad-tools button[disabled] {
  opacity: .4;
  cursor: default;
}

.fam-pad-tools button:focus-visible {
  outline: 2px solid #82301c;
  outline-offset: 2px;
}

/* ---------- Sign-in card, after Find My Friends. Use with .fam-leather-frame. ---------- */

.fam-signin {
  box-sizing: border-box;
  width: 100%;
  max-width: 500px;
  padding: 16px 14px 18px;
  color: #3a2008;
}

.fam-signin-title {
  margin: 0 0 18px;
  text-align: center;
  font: 700 24px/1.1 Georgia, "Times New Roman", serif;
  color: #1f0e02;
  text-shadow: 0 1px 0 rgba(255, 235, 195, .6), 0 -1px 0 rgba(60, 30, 5, .25);
}
