@tailwind base;
@tailwind components;
@tailwind utilities;

/* Article inline photos: wrapped in <figure class="article-figure"> by
   ApplicationHelper#article_figures so body text flows around them at a
   comfortable size. Floats only kick in at md+ (tablet/desktop); on phones the
   photo stacks full-width. Width is capped so a photo is a tasteful sidebar,
   not a wall — portraits keep their natural aspect (no crop) at that width. */
.article-figure {
  margin: 0.25rem 0 1.25rem;
}
.article-figure > img {
  width: 100%;
  margin: 0;
  border-radius: 0.75rem;
  box-shadow: 0 8px 24px rgba(20, 30, 40, 0.12);
}
.article-figure > figcaption {
  margin-top: 0.5rem;
  font-style: italic;
  text-align: center;
  color: #6b7280;
  font-size: 0.9rem;
  line-height: 1.45;
}
@media (min-width: 768px) {
  .article-figure {
    width: min(42%, 24rem);
    margin-bottom: 1rem;
  }
  .article-figure--right {
    float: right;
    margin-left: 2rem;
  }
  .article-figure--left {
    float: left;
    margin-right: 2rem;
  }
  /* Keep each principle's heading from wrapping up beside a floated photo. */
  .prose h2 {
    clear: both;
  }
}

/* Signed-in /links hub tiles (links/show, design-review item 0k, Round 2).
   The tile container itself is themed via daisyUI utility classes; only the
   colour-coded icon chip + small badge need custom rules. */
.links-ic {
  display: grid;
  place-items: center;
  width: 2.6rem;
  height: 2.6rem;
  border-radius: 0.7rem;
  color: var(--links-c);
  background: color-mix(in srgb, var(--links-c) 14%, transparent);
}
.links-ext {
  color: var(--fallback-bc, oklch(var(--bc) / 0.45));
  font-size: 0.85em;
}
.links-badge {
  display: inline-block;
  margin-top: 0.4rem;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fallback-bc, oklch(var(--bc) / 0.55));
  background: var(--fallback-b2, oklch(var(--b2) / 1));
}

/* "Browse my cards" rolodex flip-stack (business_cards/_card_rolodex,
   design-review item 8, Variant C). Without JS the deck is a plain stacked list
   of card links; the card-rolodex controller adds `.rolodex--js`, which turns it
   into an absolute deck and flips the top card away (rotateX) to reveal the next. */
.rolodex-stack {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}
.rolodex-card {
  display: flex;
  gap: 0.85rem;
  align-items: center;
  background: #fff;
  border: 1px solid #e3ded6;
  border-radius: 0.9rem;
  box-shadow: 0 6px 16px rgba(20, 30, 40, 0.08);
  padding: 0.9rem;
}
.rolodex-thumb {
  flex: none;
  width: 4rem;
  border-radius: 0.5rem;
  box-shadow: 0 3px 8px rgba(20, 30, 40, 0.18);
  display: block;
}
.rolodex-name {
  font-weight: 800;
  color: #2a2140;
  line-height: 1.15;
}
.rolodex-tag {
  color: #6b6472;
  font-size: 0.85rem;
  margin: 0.15rem 0 0.55rem;
  line-height: 1.3;
}
.rolodex-open {
  display: inline-block;
  background: #0d9488;
  color: #fff;
  font-weight: 700;
  font-size: 0.8rem;
  padding: 0.35rem 0.85rem;
  border-radius: 999px;
}
.rolodex-here {
  display: inline-block;
  color: #0a6a61;
  font-weight: 700;
  font-size: 0.75rem;
  background: #e6f5f2;
  padding: 0.35rem 0.7rem;
  border-radius: 999px;
}

/* JS-on: absolute flip deck */
.rolodex--js .rolodex-stack {
  display: block;
  position: relative;
  perspective: 1200px;
}
.rolodex--js .rolodex-card {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  transform-origin: top center;
  transition: transform 0.35s ease, opacity 0.35s ease;
  backface-visibility: hidden;
}
.rolodex--js .rolodex-card.is-top {
  transform: none;
  opacity: 1;
  z-index: 3;
}
.rolodex--js .rolodex-card.is-behind {
  transform: translateY(11px) scale(0.97) rotate(-1.4deg);
  opacity: 1;
  z-index: 1;
  filter: brightness(0.97);
}
.rolodex--js .rolodex-card.is-stashed {
  transform: translateY(15px) scale(0.94);
  opacity: 0;
  z-index: 0;
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .rolodex--js .rolodex-card.is-flipping {
    transform: translateY(-6px) rotateX(-92deg);
    opacity: 0;
  }
}

.rolodex-ctrls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
  margin-top: 1rem;
}
.rolodex-back,
.rolodex-flip {
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  border-radius: 999px;
  border: none;
}
.rolodex-back {
  background: transparent;
  color: #0a6a61;
  font-size: 0.85rem;
  padding: 0.4rem 0.6rem;
}
.rolodex-flip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  background: #0d9488;
  color: #fff;
  font-size: 0.9rem;
  padding: 0.5rem 1.1rem;
}
.rolodex-count {
  color: #8a8172;
  font-size: 0.8rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.rolodex-back:focus-visible,
.rolodex-flip:focus-visible,
.rolodex-stack:focus-visible {
  outline: 2px solid #0d9488;
  outline-offset: 2px;
}

/* Business-card scan section: teal "scan target" corner ticks framing the QR
   (design-review item 7, Variant A). */
.qr-tick {
  position: absolute;
  width: 1rem;
  height: 1rem;
  border: 2.5px solid #0d9488;
}
.qr-tick--tl { top: 7px; left: 7px; border-right: none; border-bottom: none; border-radius: 5px 0 0 0; }
.qr-tick--tr { top: 7px; right: 7px; border-left: none; border-bottom: none; border-radius: 0 5px 0 0; }
.qr-tick--bl { bottom: 7px; left: 7px; border-right: none; border-top: none; border-radius: 0 0 0 5px; }
.qr-tick--br { bottom: 7px; right: 7px; border-left: none; border-top: none; border-radius: 0 0 5px 0; }

@keyframes heart-pop {
  0% { transform: scale(1); }
  35% { transform: scale(1.4); }
  60% { transform: scale(0.9); }
  100% { transform: scale(1); }
}
.heart-pop {
  animation: heart-pop 0.35s ease;
}

.card-perspective {
  perspective: 1600px;
}
.card-inner {
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.7s;
}
.card-inner.flipped {
  transform: rotateY(180deg);
}
.card-face {
  backface-visibility: hidden;
  width: 100%;
}
.card-face.card-back {
  position: absolute;
  inset: 0;
  /* Fill the front's box exactly. The front image is in-flow and sets the
     card height from its own aspect ratio; without an explicit height +
     object-fit here, an over-constrained absolute <img> falls back to its
     OWN intrinsic aspect, so a front/back pair with slightly different
     source widths (e.g. 893x1600 vs 959x1600) renders at two different
     heights. height:100% + object-fit:cover pins the back to the front's
     box (a few px of the wider face's margin is cropped, content is
     centered and unaffected). */
  height: 100%;
  object-fit: cover;
  transform: rotateY(180deg);
}

/* A gentle Pokémon-card-style tilt: the card rocks side to side with a slight
   3D turn so it catches the eye and hints it's tappable. Kept subtle and
   short. Runs periodically via business_card_controller.js. */
@keyframes card-wiggle {
  0%, 100% { transform: rotate(0deg) rotateY(0deg); }
  15% { transform: rotate(-2.5deg) rotateY(-9deg); }
  40% { transform: rotate(2deg) rotateY(9deg); }
  65% { transform: rotate(-1.5deg) rotateY(-5deg); }
  85% { transform: rotate(1deg) rotateY(3deg); }
}
.card-wiggle {
  animation: card-wiggle 0.9s ease-in-out;
}
@media (prefers-reduced-motion: reduce) {
  .card-wiggle { animation: none; }
}

/* Corner "tap to flip" prompt. Gently pulses to draw attention; the
   controller removes it once the user has flipped the card. */
@keyframes card-hint-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}
.card-tap-hint {
  animation: card-hint-pulse 1.8s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .card-tap-hint { animation: none; }
}

/* The business-cards index "card back" tucked under the front: fade its bottom
   edge to transparent so it fills the space beside the text column without a
   hard cut, and never extends the row height past the text. */
.card-fanned-back {
  /* Fade re-tuned (design-review item 10, Variant A) to sit lower under the
     front: keeps the peek crisp where it now lands (top-[44%]) and fades only
     at the very bottom, instead of fading out mid-peek. */
  -webkit-mask-image: linear-gradient(to bottom, #000 58%, transparent 96%);
  mask-image: linear-gradient(to bottom, #000 58%, transparent 96%);
}

@keyframes flash-enter {
  0% { opacity: 0; transform: translateY(-12px); }
  100% { opacity: 1; transform: translateY(0); }
}
.flash-enter {
  animation: flash-enter 0.25s ease-out;
}
@media (prefers-reduced-motion: reduce) {
  .flash-enter { animation: none; }
}

@keyframes card-pop-shake {
  0% { transform: scale(1) rotate(0deg); }
  20% { transform: scale(1.05) rotate(-4deg); }
  40% { transform: scale(1.05) rotate(4deg); }
  60% { transform: scale(1.05) rotate(-3deg); }
  80% { transform: scale(1.05) rotate(3deg); }
  100% { transform: scale(1.05) rotate(0deg); }
}
.hover-shake:hover {
  animation: card-pop-shake 0.4s ease forwards;
}
@media (prefers-reduced-motion: reduce) {
  .hover-shake:hover { animation: none; }
}

/*

@layer components {
  .btn-primary {
    @apply py-2 px-4 bg-blue-200;
  }
}

*/

/* Bio-Well report charts (Biowell::Chart::*, app/services/biowell/chart/).
   First task to style any of these -- none of the SVG classes below had a
   single CSS rule before this. Two things every rule here has to survive:

   1. The client base skews older (feedback_older_audience_large_fonts) --
      generous font sizes, nothing hidden behind hover.
   2. The app selects a daisyUI theme per user
      (data: { theme: @theme || "cupcake" }, layouts/application.html.erb)
      from ~15 options, several of them dark (night, dracula, coffee...).
      There is no prefers-color-scheme toggle to hook -- so every colour
      below is either `currentColor` (inherits the theme's base-content
      colour automatically) or a daisyUI semantic var (--su/--er/--wa),
      which every theme defines with a contrast-safe value. Never a literal
      hex here, or a theme switch quietly breaks these charts. */

/* None of Biowell::Chart::Base's subclasses set width/height on the <svg> --
   only viewBox -- so without this every chart renders at the replaced-element
   default (300x150 CSS px), postage-stamp small regardless of its carefully
   scaled coordinate system. */
svg[class^="biowell-"] {
  display: block;
  width: 100%;
  height: auto;
  max-width: 42rem;
}
svg[class^="biowell-"] text {
  font-family: inherit;
  fill: currentColor;
}

/* Row / axis labels, legend text, "no verdict" callouts -- all secondary
   text, sized generously but kept visually quieter than data. */
.biowell-verdict-chart .label,
.biowell-band-chart .label,
.axis-label,
.no-verdict,
.legend-label,
.legend-clear {
  font-size: 15px;
  opacity: 0.72;
}
.axis-label,
.no-verdict {
  font-size: 13px;
  opacity: 0.55;
}
.legend-clear {
  cursor: pointer;
}

/* The verdict word, in colour AND text -- colour is never the only channel
   here, the word itself ("good"/"bad"/"mixed"/"neutral") is always there too.
   Tried a ::before icon glyph ahead of the word first; SVG <text> does not
   paint generated content in any browser tested (verified empirically with
   a screenshot, not assumed), so it was dead CSS and has been left out
   rather than shipped unused. The word + colour pairing is the real second
   channel. */
.item-verdict {
  font-size: 15px;
  font-weight: 700;
}
.item-verdict[data-verdict="good"]    { fill: oklch(var(--su)); }
.item-verdict[data-verdict="bad"]     { fill: oklch(var(--er)); }
.item-verdict[data-verdict="mixed"]   { fill: oklch(var(--wa)); }
.item-verdict[data-verdict="neutral"] { fill: currentColor; opacity: 0.6; }

/* Zero-deviation reference line (VerdictChart). Context, not
   data -- kept faint and dashed so it never competes with a real mark. */
.zero {
  stroke: currentColor;
  stroke-opacity: 0.3;
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
}

/* .noise is the band a reading has to clear to count. Redesigned 2026-08-08:
   it is now a <rect> CENTRED ON ZERO rather than a line centred on the mark.
   Same test either way -- |deviation| > bar is exactly "the interval excludes
   zero" -- but the copy has always described a region around the baseline
   ("inside it, a reading cannot be told apart from noise"), so the drawing now
   matches the words. Always neutral: verdict colour belongs to .point, drawn on
   top, never to the uncertainty itself. */
.noise {
  fill: currentColor;
  fill-opacity: 0.16;
}
.point {
  stroke: currentColor;
  stroke-opacity: 0.5;
  stroke-width: 1;
}

.row[data-verdict="good"] .point:not(.ghost)    { fill: oklch(var(--su)); }
.row[data-verdict="bad"] .point:not(.ghost)     { fill: oklch(var(--er)); }
.row[data-verdict="mixed"] .point:not(.ghost)   { fill: oklch(var(--wa)); }
.row[data-verdict="neutral"] .point:not(.ghost) { fill: currentColor; opacity: 0.6; }

/* The OTHER reading -- the same product measured the other way round -- drawn
   as an outline behind the one in focus (design review round 4). SHAPE says
   which reading it is (circle in the container, diamond out); FILL says which
   one you are looking at. Neither channel is colour, so a card survives
   greyscale, a printed page and any colour-vision deficiency. */
.point.ghost {
  fill: none !important;
  stroke-width: 2.5;
  stroke-opacity: 0.85;
  opacity: 0.55;
}
.point.ghost                          { stroke: currentColor; }
.point.ghost[data-verdict="good"]     { stroke: oklch(var(--su)); }
.point.ghost[data-verdict="bad"]      { stroke: oklch(var(--er)); }
.point.ghost[data-verdict="mixed"]    { stroke: oklch(var(--wa)); }

/* The number on every row -- the reason a reader never has to estimate a
   deviation off an axis label. Bold when the row cleared its own noise, which
   is the SECOND channel behind that fact: red and green never carry it alone
   (design review item 5, and roughly one man in twelve needs this). */
.biowell-verdict-chart .value {
  font-size: 17px;
  font-variant-numeric: tabular-nums;
  opacity: 0.75;
}
.biowell-verdict-chart .value.cleared {
  font-weight: 800;
  opacity: 1;
}
.value.cleared[data-verdict="good"]  { fill: oklch(var(--su)); }
.value.cleared[data-verdict="bad"]   { fill: oklch(var(--er)); }
.value.cleared[data-verdict="mixed"] { fill: oklch(var(--wa)); }

/* The bounds, drawn. The empty track either side of the marks is the pooled
   range every card shares -- it is what stops a 1% and a 50% deviation
   rendering identically -- so it is labelled rather than trimmed away. */
.axis-ruler .rule,
.axis-ruler .tick {
  stroke: currentColor;
  stroke-opacity: 0.35;
  stroke-width: 1;
}

/* A row or panel whose uncertainty could not be measured carries NO
   data-verdict at all -- the chart drops the claim rather than colouring a
   marker it cannot defend. This is the fallback those marks land on, and it
   must stay visually identical to neutral: the reader is told why in words by
   .no-uncertainty below, never by a colour they have to decode. */
.row:not([data-verdict]) .point {
  fill: currentColor;
  opacity: 0.6;
}

/* The visible stand-in for an interval that does not exist. Deliberately the
   same quiet treatment as .no-verdict -- it is a statement about what the
   session could measure, not an alarm. */
.no-uncertainty {
  font-size: 13px;
  font-style: italic;
  opacity: 0.6;
}

/* BandChart: the normative range (soft, supportive highlight), the severity
   gradient beyond it (the two <stop> classes the gradient defs reference --
   without these the gradient paints solid black, since stop-color's initial
   value is black), and .noise -- the same "cannot be told apart from noise"
   concept as .ci, but drawn as an actual rect here, so it gets the same
   deliberately-prominent treatment: wide, translucent, unmissable first. */
.norm {
  fill: oklch(var(--su) / 0.14);
}
.tier-high,
.tier-low {
  stop-color: oklch(var(--wa));
  stop-opacity: 0.32;
}
.tier-norm {
  stop-color: oklch(var(--wa));
  stop-opacity: 0;
}
.noise {
  fill: currentColor;
  fill-opacity: 0.3;
}
.band-panel .label {
  font-weight: 600;
}
/* Baseline is a hollow ring (where the trend expected them); the item is a
   solid disc (where they landed) -- shape carries the identity so colour
   isn't the only channel telling the two markers apart.

   Colour on the item marker follows `data-verdict`, the NOISE-GATED
   Biowell::Bands.verdict the engine itself stored -- never `data-movement`,
   which is a bare sign comparison and close to a coin flip. It used to follow
   movement, so on RaP's real session both Tensor rings painted GREEN on the
   client report for placements the engine had scored Neutral.

   A panel with no measurable uncertainty emits no data-verdict at all and
   lands on the neutral fallback, with .no-uncertainty saying so in words. The
   word beside the marker (.item-verdict) is the second channel, because these
   steps sit at deutan dE 4.1 and spec section 5.6 forbids colour alone. */
.baseline-level {
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  opacity: 0.75;
}
.item-level {
  stroke: currentColor;
  stroke-width: 1;
}
.band-panel[data-verdict="good"] .item-level { fill: oklch(var(--su)); }
.band-panel[data-verdict="bad"] .item-level  { fill: oklch(var(--er)); }
.band-panel[data-verdict="neutral"] .item-level,
.band-panel:not([data-verdict]) .item-level {
  fill: currentColor;
  opacity: 0.6;
}

/* A legend row for a capture with no readings on this parameter: named, so
   every capture in the session is still accounted for, but with no swatch and
   no line to focus. */
.legend-row.no-readings .legend-label {
  font-style: italic;
  opacity: 0.55;
}

/* ReplicateChart: ten points inside one capture, no verdict. An aberrant
   replicate (>3x the median residual off the fitted line) gets a second and
   third channel beyond colour -- a bigger radius and its own ring -- so it
   still reads on a greyscale printout. */
.replicate {
  fill: currentColor;
  opacity: 0.6;
}
.replicate.aberrant {
  fill: oklch(var(--wa));
  stroke: currentColor;
  stroke-width: 1.5;
  opacity: 1;
  r: 6px;
}
.decline-fit {
  fill: none;
  stroke: currentColor;
  stroke-opacity: 0.45;
  stroke-width: 2;
  stroke-dasharray: 6 4;
}

/* SessionOverlayChart: identity by focus, not hue (22 captures, nowhere
   near 22 distinguishable colours -- see the chart class comment). Every
   line starts recessive; a baseline is a little more present because it
   defines the trend everything else is read against; the biowell-overlay
   Stimulus controller toggles is-focused/is-dimmed on click. */
.capture-line {
  fill: none;
  stroke: currentColor;
  stroke-opacity: 0.22;
  stroke-width: 1.5;
}
.capture-line.baseline {
  stroke-opacity: 0.5;
  stroke-width: 2;
}
.capture-line.is-focused {
  stroke: oklch(var(--p));
  stroke-opacity: 1;
  stroke-width: 3;
}
.capture-line.is-dimmed {
  stroke-opacity: 0.06;
}
.legend-row {
  cursor: pointer;
}
.legend-swatch {
  stroke: currentColor;
  stroke-opacity: 0.4;
  stroke-width: 2;
}
.legend-row.baseline .legend-swatch {
  stroke-opacity: 0.65;
  stroke-width: 3;
}
.legend-row.is-active .legend-swatch {
  stroke: oklch(var(--p));
  stroke-opacity: 1;
  stroke-width: 3;
}
.legend-row.is-active .legend-label {
  opacity: 1;
  font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Bio-Well product cards (design review, 2026-08-08). Two columns, one card per
   product, a switcher where the product was measured both in and out of its
   container. No literal colours: the app lets each user pick from ~15 daisyUI
   themes, several of them dark, so everything here is currentColor or a
   semantic var -- a hex would break on a theme switch.
   --------------------------------------------------------------------------- */
.biowell-cards {
  display: grid;
  gap: 1rem;
  grid-template-columns: 1fr;
}
@media (min-width: 48rem) {
  .biowell-cards { grid-template-columns: 1fr 1fr; }
}

.biowell-card {
  border: 1px solid currentColor;
  border-color: color-mix(in oklch, currentColor 18%, transparent);
  border-radius: 0.5rem;
  padding: 0.75rem 0.85rem;
}
.biowell-card__head {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 0.25rem;
}
/* Ben's first note on the ledger: the name was 15px at 72% opacity -- styled as
   a caption, fainter than the axis furniture around it. It leads now. */
.biowell-card__name {
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  line-height: 1.15;
  overflow-wrap: anywhere;
}
.biowell-card__verdict {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0.2rem 0 0.35rem;
}

.biowell-chip {
  font-size: 0.95rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border: 2px solid currentColor;
  border-radius: 0.25rem;
  padding: 0.05rem 0.45rem;
}
.biowell-chip--good  { color: oklch(var(--su)); }
.biowell-chip--bad   { color: oklch(var(--er)); }
.biowell-chip--mixed { color: oklch(var(--wa)); }
.biowell-chip--neutral { opacity: 0.65; }

.biowell-face__label {
  font-size: 0.95rem;
  font-weight: 700;
  opacity: 0.7;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.biowell-face__label::before,
.biowell-key__mark {
  content: "";
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.75;
  flex: none;
}
.biowell-face__label[data-marker="diamond"]::before,
.biowell-key__mark[data-marker="diamond"] {
  border-radius: 2px;
  transform: rotate(45deg);
  background: transparent;
  border: 3px solid currentColor;
  width: 11px;
  height: 11px;
}
.biowell-key__mark[data-marker="band"] {
  width: 34px;
  height: 13px;
  border-radius: 7px;
  opacity: 0.22;
}

.biowell-switch {
  margin-left: auto;
  display: inline-flex;
  border: 2px solid currentColor;
  border-color: color-mix(in oklch, currentColor 35%, transparent);
  border-radius: 0.35rem;
  overflow: hidden;
}
.biowell-switch__btn {
  font: inherit;
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: 0.03em;
  padding: 0.15rem 0.8rem;
  background: transparent;
  border: 0;
  cursor: pointer;
  opacity: 0.6;
}
/* Both sides named explicitly. `background: currentColor` with `color` set on
   the same rule resolves the background against the NEW colour, so the pill and
   its label both went light -- the selected button rendered invisible. */
.biowell-switch__btn.is-on {
  background: oklch(var(--bc));
  color: oklch(var(--b1));
  opacity: 1;
}

.biowell-key {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.4rem;
  align-items: center;
  font-size: 1rem;
  opacity: 0.8;
  margin-bottom: 1rem;
}
.biowell-key > div {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.biowell-key dt { font-weight: 800; }
.biowell-key dd { margin: 0; }
.biowell-key__quiet { opacity: 0.7; }

/* Physician-only: the sentences under a card's charts, carrying the apparatus
   the chart deliberately omits. Quieter than the chart above them -- they are
   the detail you drop to, not the headline. */
.biowell-card__detail {
  list-style: none;
  margin: 0.4rem 0 0;
  padding: 0.5rem 0 0;
  border-top: 1px solid color-mix(in oklch, currentColor 15%, transparent);
  font-size: 0.95rem;
  font-variant-numeric: tabular-nums;
  opacity: 0.75;
}
.biowell-card__detail li { margin-bottom: 0.15rem; }

/* A switcher hides half the data, and a printed report is a real delivery
   format for this audience. On paper there is nothing to click, so both faces
   print and the switch itself does not. */
@media print {
  .biowell-face[hidden] { display: block !important; }
  .biowell-switch { display: none; }
  .biowell-cards { grid-template-columns: 1fr; }
}

/* The baseline-energy picker on a session page. Reads as a chip with a caret
   rather than a form field -- it sits in the page's header line, where the value
   is read, not down in the edit form. Colour matches the report's own three
   states; `none` and a carried value both stay neutral, because neither is a
   measurement of THIS session. */
/* inline-flex with a real max-width, NOT a bare inline span: a percentage width
   on the select resolves against its containing block, and a shrink-to-fit
   inline box gives it nothing to resolve against -- so `max-w-full` on the
   select alone measured 403px inside a 375px screen and pushed the page
   sideways. Constraining the WRAPPER is what actually caps it; min-width:0 on
   the select then lets it shrink below its longest option. Measured, not
   reasoned: 427px -> 375px. */
.biowell-energy-pick {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  /* row gap matters: at 375px the gauge wraps under the chip, and without it the
     segments sit flush against the select's bottom border and read as a progress
     bar attached to the field rather than a reading beside it. */
  gap: 0.4rem 0.55rem;
  max-width: 100%;
  /* min-width:0 is the load-bearing half. In the wizard this chip is a GRID
     item, whose automatic minimum size is min-content -- the widest option in
     the select. That forces the track wider than the screen, and `max-width:
     100%` then resolves against the track it just widened, so it caps nothing.
     Zeroing the minimum lets the track shrink and the cap apply. */
  min-width: 0;
}
.biowell-energy-pick select {
  min-width: 0;
  max-width: 100%;
  font-size: 1.05rem;
  font-weight: 700;
  padding: 0.15rem 2rem 0.15rem 0.7rem;
  /* colour comes from the wrapper so ONE value drives the chip, its caret and
     the gauge beside it -- see the [data-state] rules below */
  color: inherit;
  border: 2px solid currentColor;
  border-radius: 0.35rem;
  background-color: transparent;
  cursor: pointer;
  appearance: none;
  /* the down arrow he asked for, drawn rather than shipped as an asset */
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.05rem) 55%, calc(100% - 0.7rem) 55%;
  background-size: 0.35rem 0.35rem, 0.35rem 0.35rem;
  background-repeat: no-repeat;
}

/* Ben, 2026-08-09, choosing between three variants: "I like A and C together,
   the colors from A and the gauge from C."
   https://claude.ai/code/artifact/db56585f-b6aa-4228-a9be-e26d2b965665

   The bands used to be --in / --su / --wa, and amber read as a warning that
   Increased is not: Orientation treats Lower and Increased as SYMMETRIC
   departures from Ideal, so painting one of them like an alert says something
   the model does not.

   Measuring it turned up the bigger problem -- all three failed contrast on this
   page's own cream (#faf7f5): Lower 2.17:1, Ideal 2.84:1, Increased 1.56:1, all
   against the 4.5:1 that bold 16.8px requires (it sits under the 18.66px where
   the easier 3:1 threshold would start).

   These three are set at ONE lightness (L=0.52) so no band outranks another by
   weight, keeping the hues already chosen -- Lower cool, Increased warm. Dark
   bronze is not the warning idiom; highlighter yellow is. Literal oklch rather
   than theme tokens ON PURPOSE: the contrast guarantee is the point, and a
   daisyUI theme change must not silently undo it. Measured on the cream ground:
   4.88:1, 4.72:1, 5.26:1. */
.biowell-energy-pick[data-state="lower"]     { color: oklch(0.52 0.14 235); }
.biowell-energy-pick[data-state="ideal"]     { color: oklch(0.52 0.14 158); }
.biowell-energy-pick[data-state="increased"] { color: oklch(0.52 0.12 75); }

/* "Not established" was drawn at 0.65 opacity -- the quietest thing on the row,
   for the one state that means the report's charts are UNORIENTED. Full-strength
   ink now, with a dashed border to say "empty" rather than "disabled": it is the
   state most in need of a click, not least. */
.biowell-energy-pick[data-state="none"]        { color: oklch(var(--bc)); }
.biowell-energy-pick[data-state="none"] select { border-style: dashed; }

/* The gauge: which of the three this reading is, as position rather than colour.
   Decorative -- the select already states the value in words -- so aria-hidden,
   and it carries no meaning a colour-blind or greyscale reader loses. */
.biowell-energy-gauge {
  display: inline-flex;
  gap: 3px;
  vertical-align: middle;
}
.biowell-energy-gauge i {
  display: block;
  width: 1.6rem;
  height: 0.5rem;
  border-radius: 2px;
  background-color: transparent;
  border: 1px solid oklch(var(--bc) / 0.3);
}
.biowell-energy-pick[data-state="lower"]     .biowell-energy-gauge i:nth-child(1),
.biowell-energy-pick[data-state="ideal"]     .biowell-energy-gauge i:nth-child(2),
.biowell-energy-pick[data-state="increased"] .biowell-energy-gauge i:nth-child(3) {
  background-color: currentColor;
  border-color: currentColor;
}
/*!
 * Cropper.js v1.6.2
 * https://fengyuanchen.github.io/cropperjs
 *
 * Copyright 2015-present Chen Fengyuan
 * Released under the MIT license
 *
 * Date: 2024-04-21T07:43:02.731Z
 */

.cropper-container {
  direction: ltr;
  font-size: 0;
  line-height: 0;
  position: relative;
  -ms-touch-action: none;
      touch-action: none;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
}

.cropper-container img {
    backface-visibility: hidden;
    display: block;
    height: 100%;
    image-orientation: 0deg;
    max-height: none !important;
    max-width: none !important;
    min-height: 0 !important;
    min-width: 0 !important;
    width: 100%;
  }

.cropper-wrap-box,
.cropper-canvas,
.cropper-drag-box,
.cropper-crop-box,
.cropper-modal {
  bottom: 0;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
}

.cropper-wrap-box,
.cropper-canvas {
  overflow: hidden;
}

.cropper-drag-box {
  background-color: #fff;
  opacity: 0;
}

.cropper-modal {
  background-color: #000;
  opacity: 0.5;
}

.cropper-view-box {
  display: block;
  height: 100%;
  outline: 1px solid #39f;
  outline-color: rgba(51, 153, 255, 0.75);
  overflow: hidden;
  width: 100%;
}

.cropper-dashed {
  border: 0 dashed #eee;
  display: block;
  opacity: 0.5;
  position: absolute;
}

.cropper-dashed.dashed-h {
    border-bottom-width: 1px;
    border-top-width: 1px;
    height: calc(100% / 3);
    left: 0;
    top: calc(100% / 3);
    width: 100%;
  }

.cropper-dashed.dashed-v {
    border-left-width: 1px;
    border-right-width: 1px;
    height: 100%;
    left: calc(100% / 3);
    top: 0;
    width: calc(100% / 3);
  }

.cropper-center {
  display: block;
  height: 0;
  left: 50%;
  opacity: 0.75;
  position: absolute;
  top: 50%;
  width: 0;
}

.cropper-center::before,
  .cropper-center::after {
    background-color: #eee;
    content: ' ';
    display: block;
    position: absolute;
  }

.cropper-center::before {
    height: 1px;
    left: -3px;
    top: 0;
    width: 7px;
  }

.cropper-center::after {
    height: 7px;
    left: 0;
    top: -3px;
    width: 1px;
  }

.cropper-face,
.cropper-line,
.cropper-point {
  display: block;
  height: 100%;
  opacity: 0.1;
  position: absolute;
  width: 100%;
}

.cropper-face {
  background-color: #fff;
  left: 0;
  top: 0;
}

.cropper-line {
  background-color: #39f;
}

.cropper-line.line-e {
    cursor: ew-resize;
    right: -3px;
    top: 0;
    width: 5px;
  }

.cropper-line.line-n {
    cursor: ns-resize;
    height: 5px;
    left: 0;
    top: -3px;
  }

.cropper-line.line-w {
    cursor: ew-resize;
    left: -3px;
    top: 0;
    width: 5px;
  }

.cropper-line.line-s {
    bottom: -3px;
    cursor: ns-resize;
    height: 5px;
    left: 0;
  }

.cropper-point {
  background-color: #39f;
  height: 5px;
  opacity: 0.75;
  width: 5px;
}

.cropper-point.point-e {
    cursor: ew-resize;
    margin-top: -3px;
    right: -3px;
    top: 50%;
  }

.cropper-point.point-n {
    cursor: ns-resize;
    left: 50%;
    margin-left: -3px;
    top: -3px;
  }

.cropper-point.point-w {
    cursor: ew-resize;
    left: -3px;
    margin-top: -3px;
    top: 50%;
  }

.cropper-point.point-s {
    bottom: -3px;
    cursor: s-resize;
    left: 50%;
    margin-left: -3px;
  }

.cropper-point.point-ne {
    cursor: nesw-resize;
    right: -3px;
    top: -3px;
  }

.cropper-point.point-nw {
    cursor: nwse-resize;
    left: -3px;
    top: -3px;
  }

.cropper-point.point-sw {
    bottom: -3px;
    cursor: nesw-resize;
    left: -3px;
  }

.cropper-point.point-se {
    bottom: -3px;
    cursor: nwse-resize;
    height: 20px;
    opacity: 1;
    right: -3px;
    width: 20px;
  }

@media (min-width: 768px) {

.cropper-point.point-se {
      height: 15px;
      width: 15px;
  }
    }

@media (min-width: 992px) {

.cropper-point.point-se {
      height: 10px;
      width: 10px;
  }
    }

@media (min-width: 1200px) {

.cropper-point.point-se {
      height: 5px;
      opacity: 0.75;
      width: 5px;
  }
    }

.cropper-point.point-se::before {
    background-color: #39f;
    bottom: -50%;
    content: ' ';
    display: block;
    height: 200%;
    opacity: 0;
    position: absolute;
    right: -50%;
    width: 200%;
  }

.cropper-invisible {
  opacity: 0;
}

.cropper-bg {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
}

.cropper-hide {
  display: block;
  height: 0;
  position: absolute;
  width: 0;
}

.cropper-hidden {
  display: none !important;
}

.cropper-move {
  cursor: move;
}

.cropper-crop {
  cursor: crosshair;
}

.cropper-disabled .cropper-drag-box,
.cropper-disabled .cropper-face,
.cropper-disabled .cropper-line,
.cropper-disabled .cropper-point {
  cursor: not-allowed;
}
/* required styles */

.leaflet-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-container,
.leaflet-pane > svg,
.leaflet-pane > canvas,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
	position: absolute;
	left: 0;
	top: 0;
	}
.leaflet-container {
	overflow: hidden;
	}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
	-webkit-user-select: none;
	   -moz-user-select: none;
	        user-select: none;
	  -webkit-user-drag: none;
	}
/* Prevents IE11 from highlighting tiles in blue */
.leaflet-tile::selection {
	background: transparent;
}
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
.leaflet-safari .leaflet-tile {
	image-rendering: -webkit-optimize-contrast;
	}
/* hack that prevents hw layers "stretching" when loading new tiles */
.leaflet-safari .leaflet-tile-container {
	width: 1600px;
	height: 1600px;
	-webkit-transform-origin: 0 0;
	}
.leaflet-marker-icon,
.leaflet-marker-shadow {
	display: block;
	}
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container .leaflet-overlay-pane svg {
	max-width: none !important;
	max-height: none !important;
	}
.leaflet-container .leaflet-marker-pane img,
.leaflet-container .leaflet-shadow-pane img,
.leaflet-container .leaflet-tile-pane img,
.leaflet-container img.leaflet-image-layer,
.leaflet-container .leaflet-tile {
	max-width: none !important;
	max-height: none !important;
	width: auto;
	padding: 0;
	}

.leaflet-container img.leaflet-tile {
	/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
	mix-blend-mode: plus-lighter;
}

.leaflet-container.leaflet-touch-zoom {
	-ms-touch-action: pan-x pan-y;
	touch-action: pan-x pan-y;
	}
.leaflet-container.leaflet-touch-drag {
	-ms-touch-action: pinch-zoom;
	/* Fallback for FF which doesn't support pinch-zoom */
	touch-action: none;
	touch-action: pinch-zoom;
}
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
	-ms-touch-action: none;
	touch-action: none;
}
.leaflet-container {
	-webkit-tap-highlight-color: transparent;
}
.leaflet-container a {
	-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
}
.leaflet-tile {
	filter: inherit;
	visibility: hidden;
	}
.leaflet-tile-loaded {
	visibility: inherit;
	}
.leaflet-zoom-box {
	width: 0;
	height: 0;
	-moz-box-sizing: border-box;
	     box-sizing: border-box;
	z-index: 800;
	}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
	-moz-user-select: none;
	}

.leaflet-pane         { z-index: 400; }

.leaflet-tile-pane    { z-index: 200; }
.leaflet-overlay-pane { z-index: 400; }
.leaflet-shadow-pane  { z-index: 500; }
.leaflet-marker-pane  { z-index: 600; }
.leaflet-tooltip-pane   { z-index: 650; }
.leaflet-popup-pane   { z-index: 700; }

.leaflet-map-pane canvas { z-index: 100; }
.leaflet-map-pane svg    { z-index: 200; }

.leaflet-vml-shape {
	width: 1px;
	height: 1px;
	}
.lvml {
	behavior: url(#default#VML);
	display: inline-block;
	position: absolute;
	}


/* control positioning */

.leaflet-control {
	position: relative;
	z-index: 800;
	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
	pointer-events: auto;
	}
.leaflet-top,
.leaflet-bottom {
	position: absolute;
	z-index: 1000;
	pointer-events: none;
	}
.leaflet-top {
	top: 0;
	}
.leaflet-right {
	right: 0;
	}
.leaflet-bottom {
	bottom: 0;
	}
.leaflet-left {
	left: 0;
	}
.leaflet-control {
	float: left;
	clear: both;
	}
.leaflet-right .leaflet-control {
	float: right;
	}
.leaflet-top .leaflet-control {
	margin-top: 10px;
	}
.leaflet-bottom .leaflet-control {
	margin-bottom: 10px;
	}
.leaflet-left .leaflet-control {
	margin-left: 10px;
	}
.leaflet-right .leaflet-control {
	margin-right: 10px;
	}


/* zoom and fade animations */

.leaflet-fade-anim .leaflet-popup {
	opacity: 0;
	-webkit-transition: opacity 0.2s linear;
	   -moz-transition: opacity 0.2s linear;
	        transition: opacity 0.2s linear;
	}
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
	opacity: 1;
	}
.leaflet-zoom-animated {
	-webkit-transform-origin: 0 0;
	    -ms-transform-origin: 0 0;
	        transform-origin: 0 0;
	}
svg.leaflet-zoom-animated {
	will-change: transform;
}

.leaflet-zoom-anim .leaflet-zoom-animated {
	-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
	   -moz-transition:    -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
	        transition:         transform 0.25s cubic-bezier(0,0,0.25,1);
	}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile {
	-webkit-transition: none;
	   -moz-transition: none;
	        transition: none;
	}

.leaflet-zoom-anim .leaflet-zoom-hide {
	visibility: hidden;
	}


/* cursors */

.leaflet-interactive {
	cursor: pointer;
	}
.leaflet-grab {
	cursor: -webkit-grab;
	cursor:    -moz-grab;
	cursor:         grab;
	}
.leaflet-crosshair,
.leaflet-crosshair .leaflet-interactive {
	cursor: crosshair;
	}
.leaflet-popup-pane,
.leaflet-control {
	cursor: auto;
	}
.leaflet-dragging .leaflet-grab,
.leaflet-dragging .leaflet-grab .leaflet-interactive,
.leaflet-dragging .leaflet-marker-draggable {
	cursor: move;
	cursor: -webkit-grabbing;
	cursor:    -moz-grabbing;
	cursor:         grabbing;
	}

/* marker & overlays interactivity */
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-image-layer,
.leaflet-pane > svg path,
.leaflet-tile-container {
	pointer-events: none;
	}

.leaflet-marker-icon.leaflet-interactive,
.leaflet-image-layer.leaflet-interactive,
.leaflet-pane > svg path.leaflet-interactive,
svg.leaflet-image-layer.leaflet-interactive path {
	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
	pointer-events: auto;
	}

/* visual tweaks */

.leaflet-container {
	background: #ddd;
	outline-offset: 1px;
	}
.leaflet-container a {
	color: #0078A8;
	}
.leaflet-zoom-box {
	border: 2px dotted #38f;
	background: rgba(255,255,255,0.5);
	}


/* general typography */
.leaflet-container {
	font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
	font-size: 12px;
	font-size: 0.75rem;
	line-height: 1.5;
	}


/* general toolbar styles */

.leaflet-bar {
	box-shadow: 0 1px 5px rgba(0,0,0,0.65);
	border-radius: 4px;
	}
.leaflet-bar a {
	background-color: #fff;
	border-bottom: 1px solid #ccc;
	width: 26px;
	height: 26px;
	line-height: 26px;
	display: block;
	text-align: center;
	text-decoration: none;
	color: black;
	}
.leaflet-bar a,
.leaflet-control-layers-toggle {
	background-position: 50% 50%;
	background-repeat: no-repeat;
	display: block;
	}
.leaflet-bar a:hover,
.leaflet-bar a:focus {
	background-color: #f4f4f4;
	}
.leaflet-bar a:first-child {
	border-top-left-radius: 4px;
	border-top-right-radius: 4px;
	}
.leaflet-bar a:last-child {
	border-bottom-left-radius: 4px;
	border-bottom-right-radius: 4px;
	border-bottom: none;
	}
.leaflet-bar a.leaflet-disabled {
	cursor: default;
	background-color: #f4f4f4;
	color: #bbb;
	}

.leaflet-touch .leaflet-bar a {
	width: 30px;
	height: 30px;
	line-height: 30px;
	}
.leaflet-touch .leaflet-bar a:first-child {
	border-top-left-radius: 2px;
	border-top-right-radius: 2px;
	}
.leaflet-touch .leaflet-bar a:last-child {
	border-bottom-left-radius: 2px;
	border-bottom-right-radius: 2px;
	}

/* zoom control */

.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
	font: bold 18px 'Lucida Console', Monaco, monospace;
	text-indent: 1px;
	}

.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out  {
	font-size: 22px;
	}


/* layers control */

.leaflet-control-layers {
	box-shadow: 0 1px 5px rgba(0,0,0,0.4);
	background: #fff;
	border-radius: 5px;
	}
.leaflet-control-layers-toggle {
	background-image: url(/images/layers.png);
	width: 36px;
	height: 36px;
	}
.leaflet-retina .leaflet-control-layers-toggle {
	background-image: url(/images/layers-2x.png);
	background-size: 26px 26px;
	}
.leaflet-touch .leaflet-control-layers-toggle {
	width: 44px;
	height: 44px;
	}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
	display: none;
	}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
	display: block;
	position: relative;
	}
.leaflet-control-layers-expanded {
	padding: 6px 10px 6px 6px;
	color: #333;
	background: #fff;
	}
.leaflet-control-layers-scrollbar {
	overflow-y: scroll;
	overflow-x: hidden;
	padding-right: 5px;
	}
.leaflet-control-layers-selector {
	margin-top: 2px;
	position: relative;
	top: 1px;
	}
.leaflet-control-layers label {
	display: block;
	font-size: 13px;
	font-size: 1.08333em;
	}
.leaflet-control-layers-separator {
	height: 0;
	border-top: 1px solid #ddd;
	margin: 5px -10px 5px -6px;
	}

/* Default icon URLs */
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
	background-image: url(/images/marker-icon.png);
	}


/* attribution and scale controls */

.leaflet-container .leaflet-control-attribution {
	background: #fff;
	background: rgba(255, 255, 255, 0.8);
	margin: 0;
	}
.leaflet-control-attribution,
.leaflet-control-scale-line {
	padding: 0 5px;
	color: #333;
	line-height: 1.4;
	}
.leaflet-control-attribution a {
	text-decoration: none;
	}
.leaflet-control-attribution a:hover,
.leaflet-control-attribution a:focus {
	text-decoration: underline;
	}
.leaflet-attribution-flag {
	display: inline !important;
	vertical-align: baseline !important;
	width: 1em;
	height: 0.6669em;
	}
.leaflet-left .leaflet-control-scale {
	margin-left: 5px;
	}
.leaflet-bottom .leaflet-control-scale {
	margin-bottom: 5px;
	}
.leaflet-control-scale-line {
	border: 2px solid #777;
	border-top: none;
	line-height: 1.1;
	padding: 2px 5px 1px;
	white-space: nowrap;
	-moz-box-sizing: border-box;
	     box-sizing: border-box;
	background: rgba(255, 255, 255, 0.8);
	text-shadow: 1px 1px #fff;
	}
.leaflet-control-scale-line:not(:first-child) {
	border-top: 2px solid #777;
	border-bottom: none;
	margin-top: -2px;
	}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
	border-bottom: 2px solid #777;
	}

.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
	box-shadow: none;
	}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
	border: 2px solid rgba(0,0,0,0.2);
	background-clip: padding-box;
	}


/* popup */

.leaflet-popup {
	position: absolute;
	text-align: center;
	margin-bottom: 20px;
	}
.leaflet-popup-content-wrapper {
	padding: 1px;
	text-align: left;
	border-radius: 12px;
	}
.leaflet-popup-content {
	margin: 13px 24px 13px 20px;
	line-height: 1.3;
	font-size: 13px;
	font-size: 1.08333em;
	min-height: 1px;
	}
.leaflet-popup-content p {
	margin: 17px 0;
	margin: 1.3em 0;
	}
.leaflet-popup-tip-container {
	width: 40px;
	height: 20px;
	position: absolute;
	left: 50%;
	margin-top: -1px;
	margin-left: -20px;
	overflow: hidden;
	pointer-events: none;
	}
.leaflet-popup-tip {
	width: 17px;
	height: 17px;
	padding: 1px;

	margin: -10px auto 0;
	pointer-events: auto;

	-webkit-transform: rotate(45deg);
	   -moz-transform: rotate(45deg);
	    -ms-transform: rotate(45deg);
	        transform: rotate(45deg);
	}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
	background: white;
	color: #333;
	box-shadow: 0 3px 14px rgba(0,0,0,0.4);
	}
.leaflet-container a.leaflet-popup-close-button {
	position: absolute;
	top: 0;
	right: 0;
	border: none;
	text-align: center;
	width: 24px;
	height: 24px;
	font: 16px/24px Tahoma, Verdana, sans-serif;
	color: #757575;
	text-decoration: none;
	background: transparent;
	}
.leaflet-container a.leaflet-popup-close-button:hover,
.leaflet-container a.leaflet-popup-close-button:focus {
	color: #585858;
	}
.leaflet-popup-scrolled {
	overflow: auto;
	}

.leaflet-oldie .leaflet-popup-content-wrapper {
	-ms-zoom: 1;
	}
.leaflet-oldie .leaflet-popup-tip {
	width: 24px;
	margin: 0 auto;

	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
	}

.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
	border: 1px solid #999;
	}


/* div icon */

.leaflet-div-icon {
	background: #fff;
	border: 1px solid #666;
	}


/* Tooltip */
/* Base styles for the element that has a tooltip */
.leaflet-tooltip {
	position: absolute;
	padding: 6px;
	background-color: #fff;
	border: 1px solid #fff;
	border-radius: 3px;
	color: #222;
	white-space: nowrap;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
	pointer-events: none;
	box-shadow: 0 1px 3px rgba(0,0,0,0.4);
	}
.leaflet-tooltip.leaflet-interactive {
	cursor: pointer;
	pointer-events: auto;
	}
.leaflet-tooltip-top:before,
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
	position: absolute;
	pointer-events: none;
	border: 6px solid transparent;
	background: transparent;
	content: "";
	}

/* Directions */

.leaflet-tooltip-bottom {
	margin-top: 6px;
}
.leaflet-tooltip-top {
	margin-top: -6px;
}
.leaflet-tooltip-bottom:before,
.leaflet-tooltip-top:before {
	left: 50%;
	margin-left: -6px;
	}
.leaflet-tooltip-top:before {
	bottom: 0;
	margin-bottom: -12px;
	border-top-color: #fff;
	}
.leaflet-tooltip-bottom:before {
	top: 0;
	margin-top: -12px;
	margin-left: -6px;
	border-bottom-color: #fff;
	}
.leaflet-tooltip-left {
	margin-left: -6px;
}
.leaflet-tooltip-right {
	margin-left: 6px;
}
.leaflet-tooltip-left:before,
.leaflet-tooltip-right:before {
	top: 50%;
	margin-top: -6px;
	}
.leaflet-tooltip-left:before {
	right: 0;
	margin-right: -12px;
	border-left-color: #fff;
	}
.leaflet-tooltip-right:before {
	left: 0;
	margin-left: -12px;
	border-right-color: #fff;
	}

/* Printing */

@media print {
	/* Prevent printers from removing background-images of controls. */
	.leaflet-control {
		-webkit-print-color-adjust: exact;
		print-color-adjust: exact;
		}
	}
/*
 * This is a manifest file that'll be compiled into application.css, which will include all the files
 * listed below.
 *
 * Any CSS (and SCSS, if configured) file within this directory, lib/assets/stylesheets, or any plugin's
 * vendor/assets/stylesheets directory can be referenced here using a relative path.
 *
 * You're free to add application-wide styles to this file and they'll appear at the bottom of the
 * compiled file so the styles you add here take precedence over styles defined in any other CSS
 * files in this directory. Styles in this file should be added after the last require_* statement.
 * It is generally better to create a new file per style scope.
 *


 */

/* === BODY === */ 

.navbar, .btm-nav {
    min-height: 3.5rem !important;
    max-height: 3.5rem !important;
}

.table-row-section-title {
    text-align: center;
    text-transform: uppercase;
}

thead.table-row-header {
    font-size: medium;
}

/* Make autofill text on input fields transparent instead of mustard-yellow */
input:-webkit-autofill,
input:-webkit-autofill:focus {
    transition: background-color 600000s 0s, color 600000s 0s;
}
input[data-autocompleted] {
    background-color: transparent !important;
}

#total-points-stat {
    --tw-border-opacity: 0 !important;
    border-right-width: 0px !important;
}

.p-b-4rem {
    padding-bottom: 4rem;
}

#todays-habits-sticky-point-bar {
    --tw-bg-opacity: 1;
    background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
    position: sticky;
    padding-top: 0.5rem;
    top: 0;
    width: 100%;
    z-index: 1;
}

#dashboard-todays-statistics-point-bar {
    --tw-bg-opacity: 1;
    background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity)));
    text-align: center;
    width: 100%;
}

.text-right {
    text-align: right;
}

.pr-4 {
    padding-right: 1rem;
}

.prose {
    max-width: 100%;
}

.prose p {
    margin-top: 0.5rem;
    margin-bottom: 0.75rem;
}

.prose p.m-0 {
    margin-top: 0;
    margin-bottom: 0;
    margin-right: 0;
    margin-left: 0;
}

.mt-minus-2 {
    margin-top: -0.5rem;
}

.h-full {
    height: 100%;
}

td.no-padding {
    padding: 0 !important;
    a {
        padding: 0.5rem 1rem;
    }
}

/* Study accordion More / Less (Preview / Full) button styles */
.summary-preview {
    height: 1.5rem;
    overflow: hidden;
  }
.summary-full {
    padding-top: 10px;
}

.tabs-boxed {
    border-radius: 0;
}
.to-bg-primary {
    --tw-bg-opacity: 1;
    --tw-gradient-to: oklch(var(--b1));
}

/* Horizontally scrolling list of books */
.carousel {
    overflow-x: auto;
    padding: 20px;
  }
  
.carousel-item {
    margin-right: 20px;
}
  
.carousel-item:last-child {
    margin-right: 0;
}

.carousel.pl-0 {
    padding-left: 0;
}
  
.bottom-spacer {
    margin-bottom: 4rem;
}
    
.carousel {
    justify-content: start;
}
  
.tooltip-pointer {
    position: relative;
}

.tooltip-pointer::after {
    content: "";
    position: absolute;
    bottom: -20px;
    right: 36px;
    border-width: 10px;
    border-style: solid;
    border-color: rgb(38 38 38/var(--tw-bg-opacity)) transparent transparent transparent; 
}

.shake {
    animation: shake 0.5s;
}

@keyframes shake {
    0% {
        transform: translateX(0);
    }
    20% {
        transform: translateX(-4px);
    }
    40% {
        transform: translateX(4px);
    }
    60% {
        transform: translateX(-4px);
    }
    80% {
        transform: translateX(4px);
    }
    100% {
        transform: translateX(0);
    }
}

.diff-resizer {
    width: 144px;
}

.highlighted {
    background-color: oklch(0.76172 0.089459 200.027); /* highlight color for Quotes of Studies */
    border-radius: 0.5rem;
    .bg-gradient-to-b {
        background: none;
    }
}

.dot {
    display: inline-block;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    margin: 0 2px;
}

.dot__sm {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin: 0 1px;
}
  
.green-dot {
    background-color: #34C759;
}
  
.grey-dot {
    background-color: #ccc;
}
  
/* Monthly statistics calendar */
.monthly-calendar {
    width: 100%;
    text-align: center;
  }
  
  .monthly-calendar table {
    border-collapse: collapse;
    width: 100%;
  }
  
  .monthly-calendar th,.monthly-calendar td {
    border: 1px solid #ddd;
    padding: 0;
  }
  
  .monthly-calendar table td {
    justify-content: center;
  }
  
  .day-container {
    position: relative;
    display: flex;
    justify-content: center;
  }
  
  .day-box {
    width: 40px;
    height: 40px;
    border-radius: 5px;
    /* border-radius: 50%; */ /* Do we like circles or rounded squares? */
    margin: 5px;
    display: flex;
    justify-content: center;
  }
  
  .day-number {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 14px;
    font-weight: bold;
  }  
  
  .points_200 {
    background-color: oklch(0.87497 0.24613 297.068);
  }
  
  .points_180 {
    background-color: oklch(0.85135 0.20755 275.936);
  }
  
  .points_160 {
    background-color: oklch(0.82757 0.16831 255.132);
  }
  
  .points_140 {
    background-color: oklch(0.80364 0.12843 235.131);
  }
  
  .points_120 {
    background-color: oklch(0.77953 0.08834 216.508);
  }
  
  .points_100 {
    background-color: oklch(0.76172 0.089459 200.027);
  }
  
  .points_80 {
    background-color: oklch(0.76172 0.089459 200.027);
    opacity: 0.8;
  }
  
  .points_60 {
    background-color: oklch(0.76172 0.089459 200.027);
    opacity: 0.6;
  }
  
  .points_40 {
    background-color: oklch(0.76172 0.089459 200.027);
    opacity: 0.4;
  }
  
  .points_low {
    background-color: oklch(0.76172 0.089459 200.027);
    opacity: 0.2;
  }
  
  .points_0 {
    background-color: #fff;
  }

  h1 {
    align-items: center;
    font-size: 1.25rem;
    font-weight: 600;
    gap: .5rem;
    line-height: 1.75rem;
  }
  @media (min-width: 1024px) {
    h1 {
      font-size: 1.875rem;
      line-height: 2.25rem;
      margin-bottom: 1rem;
    }
  }

/* Guest nav: horizontally scrollable category tabs with no visible scrollbar
   (touch/swipe scrolling still works — only the scrollbar itself is hidden).
   Reset to overflow: visible at md+: setting overflow-x alone implicitly makes
   overflow-y clip too, which would cut off the desktop dropdown drawer (an
   absolutely-positioned descendant) even though it's positioned relative to
   <nav>, not this container. Desktop has no need to scroll here anyway. */
.guest-nav-scroll {
    overflow-x: auto;
    scrollbar-width: none; /* Firefox */
}
.guest-nav-scroll::-webkit-scrollbar {
    display: none; /* Chrome, Safari, Edge */
}
@media (min-width: 768px) {
    .guest-nav-scroll {
        overflow: visible;
    }
}

/* Guest nav desktop dropdown: recolor a link's label on hover. Plain CSS
   descendant-of-:hover rather than Tailwind's group-hover, since the dropdown
   link already sits inside the trigger's own `group` wrapper and an unnamed
   nested group would cross-talk with it. */
.guest-nav-dropdown-link:hover .guest-nav-dropdown-label {
    color: oklch(var(--p) / 1);
}
