/* Pocket Factory design tokens. This is the one file to edit.
 *
 * Each token is a CSS custom property, so the cascade can change it for one device or one part:
 *   <pf-knob style="--shadow: 0"></pf-knob>   this knob casts no shadow
 *   pf-pad { --radius: .2 }                    the keys of the pad get sharper corners
 *
 * The shape tokens are numbers in units. --u is the only length: one unit in pixels.
 * A part reads the tokens when it connects and on a `pf-tokens` event, never in each frame.
 */

@property --u { syntax: '<length>'; inherits: true; initial-value: 12px; }
/* --stitch does not inherit, so the parts on a stitched case get no stitches. */
@property --stitch { syntax: '<number>'; inherits: false; initial-value: 0; }
/* --height: the height of one part above its surface, in units. With none, a part has the height of its kind (HEIGHT in
   lighting.js). It does not inherit, so a device with --height does not lift the parts on it. */
@property --height { syntax: '*'; inherits: false; }

:root {
  /* ---------- light ---------- */
  --light-az: 210;          /* the direction toward the light, in degrees: 0 right, 90 down, 210 up and to the left */
  --light-el: 38;           /* the height of the light above the desk, in degrees */
  --ambient: .55;           /* the light on a surface that faces away from the light */

  /* ---------- lighting layer: 1 is the default strength, and 0 turns the effect off ---------- */
  --shadow: 1;              /* the shadow that a part casts */
  --shadow-length: 1;
  --shadow-soft: 1;
  --reflect: 1;             /* the light that a part bounces onto the surface next to its lit side */
  --glow: 1;                /* the light of a part that is on: an LED, the lamp, a port with power */
  --rim: 1;                 /* the lit edge of a part */
  --grain: 1;               /* the texture of the material, and the grain of the desk */

  /* ---------- shape, in units ---------- */
  --u: min(calc((100vw - 32px) / 88), calc((100dvh - 32px) / 46));
  --radius: .45;            /* the corners of keys and small parts */
  --radius-device: 1.5;     /* the corners of a device case */
  --gap: .14;               /* the gap round a part in its hole */
  --emboss-depth: .15;      /* how deep pf-emboss is pressed in, or how high it is raised */
  /* the seat of a part: the surface sets it, see the seats below */
  --seat-edge: 0;           /* the width of the wall of the hole: 0 is a hairline of 1 px, and a wider wall is a rounder edge */
  --seat-wall: .3 .5;       /* the light of the wall: on its side that faces the light, and on its side away from the light */
  --seat-depth: 0;          /* how deep the floor of the hole is, for the shadow of the rim on the floor */
  --margin: 0;              /* the room from the edge of a surface to the parts on it */
  --seat-radius: auto;      /* the corner of the hole, in units: auto is the corner of the part plus the gap */

  /* ---------- color ---------- */
  /* the theme: --primary, --secondary, --tertiary, --accent, --desk and --ink. Each part takes its color from a role,
     or from a role mixed with black or white, so a new value of a role recolors each part that takes it. Theme in
     src/react sets them. The lights and the glass keep their own colors. */
  --primary: #d4d4d2;       /* the case of a device and its metal: a screw, a port, the grill */
  --secondary: #ecebe6;     /* the controls on a case: a key, a knob, a switch, a fader */
  --tertiary: #2a2a2c;      /* the dark parts: a graphite knob, the pad, a speaker. Keep it dark: the pad prints light text */
  --desk: #e8e7e4;
  --ink: #1d1d1f;           /* printed text */
  --mark: var(--ink);       /* the indicator of a knob, the icon on a key */
  --ink-soft: #8b8b8e;
  --paper: #f7f6f3;         /* the flat ui (the ui page): a field, the active pill of a segmented control */
  --line: #d3d2ce;          /* the flat ui: a hairline that runs the full length of a row */
  --accent: #ff5a1f;        /* signal orange */
  --led-on: #ff4a1c;
  --dot: #e1250c;           /* the dot printed on the round cap of a key */
  --signal-r: #ff3b2f;      /* the three signals of the rgb module: its lenses, and the ring of a jack with that signal */
  --signal-g: #2fd35a;
  --signal-b: #2f7bff;
  --aluminum: var(--primary);
  --bone: var(--secondary);
  --graphite: var(--tertiary);
  --keybed: #171717;
  --glass: #c8d5ce;
  --cable-1: var(--accent);
  --cable-2: var(--tertiary);
  --cable-3: color-mix(in oklab, var(--secondary), white 19%);
  --cable-fleck: #f6f4ee;   /* the tracer yarn of a braided cable */
  --plug-metal: #c4c5c7;    /* the steel of a plug: the jack plug, and the tip of a molded plug */
  --tie: #252527;           /* the nylon of a zip tie */
  --lens: #26469a;          /* the blue coating of the element in a camera lens */
  --silicone: #768baa;      /* the blue gray silicone of a speaker foot */
  --milk: #c4c2be;          /* the frosted diffuser of a light that is off */

  /* ---------- type ---------- */
  --font: 'Geist', ui-sans-serif, system-ui, sans-serif;
  --mono: ui-monospace, 'SF Mono', Menlo, monospace;   /* code */
  --edge: clamp(16px, 4vw, 24px);   /* the side space of a page and of its header */
  --label-size: .62;        /* printed labels, in units */

  /* ---------- feel ---------- */
  --detents: 24;            /* the clicks of a knob in one turn */
  --snap-radius: 34;        /* the distance in pixels from a port at which a plug snaps in */
  --cable-width: .6;        /* in units */
  --cable-spec: .85;        /* the gloss of a cable: the strength of its highlight */
  --cable-gloss: 60;        /* and its size: a higher gloss gives a smaller, sharper highlight */
  --cable-sat: .35;         /* how much deeper and more saturated the dark side of a colored cable gets */
  --swing-stiffness: 150;   /* the spring that pulls each point of a cable toward its route: lower trails more */
  --swing-damping: 7;       /* the damping of that spring: lower swings longer */
  --coil-width: 1.8;        /* the outer width of a curly cable, in units */
  --coil-pitch: .62;        /* the length of one turn of a curly cable at rest, in units */
  --coil-rest: .25;         /* the length of a curly cable at rest, as a part of its full length */
}

/* A rope is thicker than a molded cable. */
pf-cable[variant=braid], pf-cable[variant=check], pf-cable[variant=dots], pf-cable[variant=twist] { --cable-width: .85; }
/* Silicone is soft and matte: a little thicker, with a broad, faint sheen and no sharp highlight. */
pf-cable[variant=silicone] { --cable-width: .72; --cable-spec: .3; --cable-gloss: 10; --cable-sat: .15; }
pf-cable { --led-on: #ffa31a; }   /* the light of a magsafe plug in a port: amber, as while it charges */

/* A phone in portrait: the devices go in two columns. */
@media (max-width: 720px) and (orientation: portrait) {
  :root { --u: min(calc((100vw - 16px) / 46), calc((100dvh - 32px) / 76)); }
}

/* ---------- the color of each part ---------- */
pf-key { --color: color-mix(in oklab, var(--secondary), black 9%); }
pf-key[variant=slot] { --color: color-mix(in oklab, var(--tertiary), white 9%); }
pf-knob { --color: var(--graphite); --mark: var(--accent); }
pf-knob[variant=well], pf-knob[variant=rotary] { --color: color-mix(in oklab, var(--secondary), black 17%); }
pf-knob[variant=skirt] { --color: var(--bone); }
pf-knob[variant=ramp] { --color: var(--aluminum); }
pf-disc { --color: color-mix(in oklab, var(--secondary), black 12%); --mark: var(--ink); }
pf-switch { --color: color-mix(in oklab, var(--secondary), black 2%); }
pf-selector { --color: var(--aluminum); }
pf-glyph { --color: #f4f6ff; }
pf-led { --color: var(--led-on); }
pf-led[variant=flash] { --color: #ffbf4a; }
pf-lcd { --color: var(--glass); --ink: #1d1d1f; }   /* the segments stay dark when a theme gives a light --ink */
pf-bars { --color: #0f1012; }   /* the black glass of the screen */
pf-lens { --color: color-mix(in oklab, var(--primary), black 15%); }
pf-screw { --color: color-mix(in oklab, var(--primary), black 6%); }
pf-port { --color: color-mix(in oklab, var(--primary), black 17%); }
pf-roller { --color: color-mix(in oklab, var(--secondary), white 55%); }
pf-roller[variant=notch] { --color: color-mix(in oklab, var(--tertiary), black 14%); --mark: #8fc3e0; }   /* the ring on the outer cap */
pf-encoder { --color: color-mix(in oklab, var(--secondary), black 6%); --mark: color-mix(in oklab, var(--secondary), black 24%); }   /* the dome; the knurled skirt */
pf-fader { --color: color-mix(in oklab, var(--secondary), black 26%); --keybed: #0f0f0f; }
pf-meter { --color: #ff7a3a; --keybed: #808083; }   /* the light; the holes */
pf-button { --color: color-mix(in oklab, var(--secondary), black 23%); --radius: .25; }
pf-usb { --color: color-mix(in oklab, var(--primary), black 8%); --ink: #3a3a3c; }
pf-tab { --color: color-mix(in oklab, var(--secondary), black 5%); }
pf-clip { --cable-width: 1.1; }   /* on braided cables; the material gives the metal */
pf-pipe { --pipe-width: 1.6; --pipe-bend: 1.6; }   /* in units: the width of the tube, and the radius of a bend at its middle */
pf-qr { --emboss-depth: .07; }   /* a shallow etch */
pf-kill { --color: var(--dot); --mark: #d2d3d5; }   /* the cover; the steel of the toggle */
pf-tx6 { --color: #b5b5b7; --radius-device: 1.195; --ink: #1e1e20; }
pf-tx6 pf-knob { --color: #bbbbbd; --mark: #211f2a; }
pf-tx6 pf-knob.b { --mark: #f54e0b; }
pf-tx6 pf-knob.c { --mark: #ece0d7; }
pf-tx6 pf-lcd { --color: #d2e4ed; --ink: #252630; }
pf-tx6 pf-led.dot { --color: #ff6a2a; }
pf-tx6 pf-led.usb { --color: #4dff57; }
pf-tx6 pf-led.shift { --color: #ffffff; }
pf-tx6 .fx1 { --mark: #222129; }
pf-tx6 .fx2 { --mark: #f34f14; }
pf-tx6 pf-button[variant=rect] { --color: #aaaaaa; }
pf-tx6 pf-button.shift { --color: #a0a0a0; }
pf-tx6 pf-port { --color: #747474; }
pf-riddim { --color: #ded3c1; --radius-device: .15; --ink: #08452c; --accent: #fe5a0e; --label-size: .45; --keybed: #050505; }
pf-riddim[material] > * { --gap: .07; --seat-radius: .05; --seat-edge: .03; }   /* tight holes with nearly square corners */
pf-riddim pf-key { --color: #e2d6c4; --mark: #08452c; }
pf-riddim pf-key.num { --color: #e4e4e2; }
pf-riddim pf-key.orange { --color: #f54a06; --mark: #fff6ee; }
pf-riddim pf-key.green { --color: #034a36; --mark: #f1faf5; }
pf-riddim pf-key.enter { --mark: #f3481d; }
pf-riddim pf-knob { --color: #eeedea; }
pf-riddim pf-knob.x { --color: #fe5716; }
pf-riddim pf-knob.y { --color: #034231; }
pf-riddim pf-led { --color: #ff3d0f; }
pf-riddim pf-fader { --color: #e6dccb; --mark: #08452c; }
pf-riddim pf-glass { --color: #34aa83; --glass-veil: .04; }
pf-riddim pf-digits { --color: #e8fdfd; }
pf-riddim pf-plate.label { --color: #eeede9; }
pf-riddim pf-plate.grill { --color: #e9dfcf; }
pf-riddim pf-screw { --color: #5a5c5e; }
pf-riddim pf-speaker { --color: #141312; }
pf-slab { --color: #3e3e3e; --radius-device: .56; --ink: #646464; --label-size: .34; --keybed: #161616; }
pf-slab[material] > *, pf-slab .metal > * { --gap: .11; --seat-radius: .08; --seat-edge: .05; }   /* thin dark frames round the keys */
pf-slab .metal { --color: #a3a3a3; --radius-device: 0; --shadow-length: .3; }   /* the panel of metal: square, and a short step down to the face */
pf-slab pf-key { --color: #444444; --radius: .06; }
pf-slab pf-key.pad { --color: #3b3b3b; }
pf-slab .metal pf-key { --color: #a6a6a6; --mark: #ffffff; }
pf-slab .metal pf-key.round { --color: #9c9c9c; --radius: 99; --gap: .16; --seat-radius: auto; }   /* a round hole */
pf-slab pf-knob[variant] { --color: #474747; }
pf-slab .metal pf-knob[variant] { --color: #a8a8a8; }
pf-slab pf-lcd { --color: #1c1c1c; --ink: #c4c4c4; --radius: .16; }
pf-slab pf-led { --color: #ffffff; }
pf-slab pf-meter { --color: #ffffff; --keybed: #262626; }
pf-slab pf-plate { --color: #383838; }
pf-slab .logo { --label-size: .8; color: #ececec; letter-spacing: .3em; font-weight: 700; }
pf-slab .jack { --label-size: .62; color: #ececec; } pf-slab .metal .jack { color: #2e2e2e; }   /* in and out: as large as on the other devices, and clear on the face and on the metal */
pf-grill { --color: color-mix(in oklab, var(--primary), black 6%); }
pf-speaker { --color: color-mix(in oklab, var(--tertiary), black 21%); }
pf-device, pf-battery { --color: var(--aluminum); }
pf-dial { --color: var(--bone); }
pf-pad { --color: var(--graphite); --ink: #ebeae6; --ink-soft: #8e8e91; }
pf-pad pf-key { --color: color-mix(in oklab, var(--secondary), black 7%); }
pf-rgb { --color: var(--graphite); --ink: #ebeae6; --ink-soft: #8e8e91; }
pf-rgb pf-led.r { --color: var(--signal-r); } pf-rgb pf-led.g { --color: var(--signal-g); } pf-rgb pf-led.b { --color: var(--signal-b); }
pf-port[signal=r] { --accent: var(--signal-r); } pf-port[signal=g] { --accent: var(--signal-g); } pf-port[signal=b] { --accent: var(--signal-b); }
pf-display { --color: var(--bone); }
pf-lamp { --color: var(--accent); --ink-soft: color-mix(in oklab, var(--accent), black 40%); }
pf-lamp .pf-lens { --lamp-light: #fff0d6; --color: color-mix(in oklab, var(--lamp-light) var(--level, 100%), #a8642e); }   /* a dial dims it toward amber (--level, from pf-lamp.js) */
pf-keyboard { --color: var(--aluminum); }
pf-keyboard pf-knob { --color: #19191a; --mark: #19191a; }   /* black spun knobs with no mark: the teeth show the turn */
pf-keycap { --color: #eef0ed; --ink: #707273; }
pf-keycap.accent { --color: var(--accent); --ink: #fff4ec; }
pf-screen { --color: #ff7a00; --screen-mid: #fff783; --ink: #ffffff; --mark: #e6f53f; }   /* the glow from the top down to --screen-mid; the time; the date */
pf-frost { --color: #f2f3f1; --frost-milk: .42; --frost-blur: .35; }   /* the milk of the glass; how much of it covers the parts behind; the blur for one unit of distance */

/* ---------- materials ----------
 * A part sets its own material attribute when it connects, so it never takes the material of its device.
 * --spec and --gloss: the strength and the size of the specular highlight (a high gloss gives a small, sharp highlight).
 * --sat: how much deeper and more saturated the dark side of a colored surface gets.
 * --texture: grain, cloud, leather, cloth, webbing or melange, and --texture-amount its strength.
 * --stitch: the distance in units from the edge to a row of stitches round the top; 0 gives no stitches.
 * --sheen: the soft light of a fabric where it turns away from the eye, as the edge of velvet, from 0 (none) to 1.
 * The click tokens give the sound of the material, as one tick of sonics (src/core/sound.js): a noise burst through a
 * band-pass filter that rings at --click-freq (Hz) with --click-q, and fades in --click-decay (s); --click-tail is the
 * level of its sine tail and --click-bright the level of its bright attack, from 0 to 1. */
[material] { --mirror: 0; --sheen: 0; }   /* only the polished metals below mirror the studio, a part has a sheen only when it asks for one, and a part does not take either from its device */
[material=plastic] { --spec: .14; --gloss: 9;  --sat: .35; --texture: grain; --texture-amount: .18; --click-freq: 2600; --click-q: 6; --click-decay: .004;  --click-tail: .5; --click-bright: .4; }
[material=metal]   { --spec: .5;  --gloss: 26; --sat: 0;   --texture: cloud; --texture-amount: .2; --click-freq: 3120; --click-q: 7; --click-decay: .0032; --click-tail: .6; --click-bright: .55; }
[material=rubber]  { --spec: .03; --gloss: 3;  --sat: .15; --texture: grain; --texture-amount: .22; --click-freq: 1400; --click-q: 5; --click-decay: .006;  --click-tail: .8; --click-bright: .25; }
[material=glass]   { --spec: .9;  --gloss: 60; --sat: 0;   --texture: none;  --texture-amount: 0;   --click-freq: 4200; --click-q: 9; --click-decay: .0018; --click-tail: .3; --click-bright: .7; }
[material=leather] { --spec: .05; --gloss: 4;  --sat: .3;  --texture: leather; --texture-amount: .24; --click-freq: 900; --click-q: 3; --click-decay: .007; --click-tail: .6; --click-bright: .15; }
[material=cloth]   { --spec: .02; --gloss: 2;  --sat: .25; --texture: cloth; --texture-amount: .3; --click-freq: 700; --click-q: 2; --click-decay: .008; --click-tail: .3; --click-bright: .1; }
/* webbing: the nylon of a strap. A coarser weave with a sheen, stitched round its edge. */
[material=webbing] { --spec: .1; --gloss: 3; --sat: .3; --texture: webbing; --texture-amount: .55; --stitch: .55; --click-freq: 800; --click-q: 2.5; --click-decay: .007; --click-tail: .3; --click-bright: .15; }
/* melange: the wool of a speaker front. A coarse weave of heathered yarn, light and dark fibers in each thread, and no shine. */
[material=melange] { --spec: .01; --gloss: 2; --sat: .1; --texture: melange; --texture-amount: 1; --click-freq: 650; --click-q: 2; --click-decay: .009; --click-tail: .3; --click-bright: .08; }
[material=silicone] { --spec: .08; --gloss: 4; --sat: .2; --texture: grain; --texture-amount: .04; --click-freq: 1100; --click-q: 3; --click-decay: .009; --click-tail: .7; --click-bright: .1; }
/* frost: glass with a matte face, as sandblasted acrylic: a wide soft sheen and a fine grain. */
[material=frost] { --spec: .3; --gloss: 5; --sat: 0; --texture: grain; --texture-amount: .06; --click-freq: 3600; --click-q: 5; --click-decay: .0024; --click-tail: .25; --click-bright: .4; }
/* gold, chrome, gunmetal: polished metal that mirrors a small studio (polish() in light.js), so its bands slide when the
 * light moves. Each one gives its color. A flat top stays even, and its polished edge shows the move. */
[material=gold]     { --color: #fdd286; --mirror: 1; --spec: .6; --gloss: 40; --sat: 0; --texture: none; --texture-amount: 0; --click-freq: 3120; --click-q: 7; --click-decay: .0032; --click-tail: .6; --click-bright: .55; }
[material=chrome]   { --color: #f5f9ff; --mirror: 1; --spec: .6; --gloss: 40; --sat: 0; --texture: none; --texture-amount: 0; --click-freq: 3120; --click-q: 7; --click-decay: .0032; --click-tail: .6; --click-bright: .55; }
[material=gunmetal] { --color: #5b5c61; --mirror: 1; --spec: .6; --gloss: 40; --sat: 0; --texture: none; --texture-amount: 0; --click-freq: 3120; --click-q: 7; --click-decay: .0032; --click-tail: .6; --click-bright: .55; }
/* satin: the same metal, bead-blasted, as a frosted handle. --rough (0 to 1) blurs the studio, so its bands are wide and
 * soft. Any part takes --mirror (how much it mirrors the studio) and --rough, and does not take them from its device. */
[material] { --rough: 0; }
[material=satin]    { --color: #dddedf; --mirror: 1; --rough: .85; --spec: .3; --gloss: 12; --sat: 0; --texture: grain; --texture-amount: .05; --click-freq: 3120; --click-q: 7; --click-decay: .0032; --click-tail: .6; --click-bright: .55; }

/* ---------- seats ----------
 * The surface sets the spacing of the parts on it. These rules go on the children of a surface, so the hole of a part
 * comes from the material of the face, not from the part, and a part on the desk gets the values of :root.
 * Metal is machined: a tight gap and a crisp lit edge. Plastic is molded: a softer edge. Rubber and silicone are soft:
 * a wide gap and a wide, soft edge. The stitched materials also keep a margin, so the parts stay clear of the stitches.
 * The side nav lists only the rules that are exactly [material=x], so these do not show there. */
[material=metal] > *, [material=gold] > *, [material=chrome] > *, [material=gunmetal] > *, [material=satin] > * { --gap: .08; --seat-edge: .07; --seat-wall: .85 .3; }
[material=plastic] > * { --gap: .14; --seat-edge: .12; --seat-wall: .35 .45; }
[material=rubber] > *, [material=silicone] > * { --gap: .22; --seat-edge: .2; --seat-wall: .5 .3; }
[material=leather] > *, [material=cloth] > *, [material=webbing] > *, [material=melange] > * { --gap: .18; --seat-edge: .12; --seat-wall: .3 .5; --margin: .8; }
[material=webbing] > * { --margin: 1.1; }
