/* Range-bar marks — the single home for how a value is drawn against a target range.
   Values come from design-tokens.css; this file is the grammar that uses them.

   Every mark here encodes a fact about the data, so none of them may vary between screens:
   the faded zone edge says the bound is soft by MacroAcceptanceTolerance, the notch says
   where the bound is, the grey continuation distinguishes a fill that passed the ceiling
   from one that landed on it. What MAY vary is scale — set --rb-track-height per host.

   A second home for any of these values is how the last divergence happened: the compare
   bars kept a dashed-border zone for months after the canvas moved to a faded one. */

.rb-bar {
  --rb-track-height: 9px;
  /* A span with a height and no display is an inline box, and height does not apply to one.
     It has worked so far only because its host happens to be flex; the compare bars adopt this
     file next and their host may not be. */
  display: block;
  position: relative;
  height: var(--rb-track-height);
  border-radius: 999px;
  background: var(--fs-bg-tertiary, #f3f4f6);
}

/* The shaded band between the bounds. Fades at both ends; a one-sided range simply runs to
   the edge it has no bound on, and the modifiers below drop that side's fade with it. */
.rb-zone {
  position: absolute;
  top: 0;
  bottom: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--rb-zone-color) var(--fs-range-zone-fade),
    var(--rb-zone-color) calc(100% - var(--fs-range-zone-fade)),
    transparent 100%
  );
}

/* Open at the start: no floor, so nothing to fade in from. */
.rb-zone--open-start {
  border-radius: 999px 0 0 999px;
  background: linear-gradient(
    90deg,
    var(--rb-zone-color) 0%,
    var(--rb-zone-color) calc(100% - var(--fs-range-zone-fade)),
    transparent 100%
  );
}

/* Open at the end: no ceiling, so the band runs to the track's end. */
.rb-zone--open-end {
  border-radius: 0 999px 999px 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--rb-zone-color) var(--fs-range-zone-fade),
    var(--rb-zone-color) 100%
  );
}

/* The value. Full track height: a notch has to cut the whole fill to read as a bound, and an
   inset fill leaves the notch floating above it. */
.rb-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 999px;
  background: var(--rb-fill-color);
}

/* Logging a food is the core loop and this bar is the only feedback above the fold on mobile;
   without a transition it teleports on re-render and nothing signals that the tap landed. */
@media (prefers-reduced-motion: no-preference) {
  .rb-fill,
  .rb-overshoot,
  .rb-wash {
    transition:
      width 0.25s ease,
      left 0.25s ease;
  }
}

/* Squared off where the grey takes over, so the two read as one continuous bar. */
.rb-fill--continues {
  border-radius: 999px 0 0 999px;
}

/* Past the ceiling. Never red. */
.rb-overshoot {
  position: absolute;
  top: 0;
  bottom: 0;
  /* Clear the ceiling notch. The notch straddles the bound, so it covers the first 1px of any
     overshoot (2px wide, offset half its width): 50 kcal over a 2200 ceiling is 3.6px on a
     200px strip and simply vanished, making "just over" and "exactly on it" identical. Three
     notch-widths is more than that needs — the surplus is deliberate, so the arrowhead has
     something to sit on rather than being a sliver. */
  min-width: calc(var(--fs-range-notch-width) * 3);
  border-radius: 0 999px 999px 0;
  background: var(--fs-range-overshoot);
}

/* Ran off the end of the track. The arrowhead says "and beyond", which a flat end cannot.
   On a floor-only row this takes the macro colour instead — passing a floor is not going
   over range — which the markup does by pointing it at .rb-fill rather than .rb-overshoot. */
.rb-terminus {
  /* No radius of its own: the polygon removes the pointed end, and each host keeps the left
     end it should have — round on the fill, which starts at the track's own edge, square on
     the overshoot, which butts against the fill. */
  clip-path: polygon(
    0 0,
    calc(100% - var(--fs-range-terminus)) 0,
    100% 50%,
    calc(100% - var(--fs-range-terminus)) 100%,
    0 100%
  );
}

/* A bound. Sits ABOVE the fill: drawn underneath, a bar at or past its ceiling erases its
   own range exactly where the range matters most. */
.rb-notch {
  position: absolute;
  /* Overhangs the track rather than sitting inside it, and that is what makes a solid mark
     workable. The previous answer was a white core with a ring, but a 1px ring around a 2px×12px
     box closes on all four sides and reads as a bracket glyph — "[]" — not a goal line.
     Nothing wins on contrast INSIDE the track: dark loses to the dark calories fill, light loses
     to the pale track. So the ends do the work — they are always against the page — and the
     crossing is just continuity. Fixed length, not a percentage: 25% left the 6px calorie strip
     with 1.5px of mark outside the bar, which is not a mark. */
  top: calc(var(--fs-range-notch-overhang) * -1);
  bottom: calc(var(--fs-range-notch-overhang) * -1);
  width: var(--fs-range-notch-width);
  /* Straddle the bound rather than starting at it. Offset to the right, the ceiling notch
     lands in the overshoot's first two pixels and never cuts the fill, so the two bounds get
     marked asymmetrically — the floor reads "here" and the ceiling reads "just past". */
  margin-left: calc(var(--fs-range-notch-width) / -2);
  background: var(--fs-range-notch-color);
  border-radius: 1px;
  z-index: 1;
}

/* The zone's second material. Same band, same edges, same extent — but where the fill is
   underneath, the tint has nothing to be pale against, so lightness carries it instead. White
   at low alpha is the one channel that survives all four macro colours AND the dark calories
   fill, where darkening would fail.

   Sits above the fill and below the notches. Without it the band appeared to be eaten from the
   left as the day filled, reading as "how much of my range is left" rather than "where my range
   is" — and it disappeared completely at on target and over, the two states the range exists
   for. In the over state the band is now at full width exactly where it matters most. */
.rb-wash {
  --rb-wash-color: rgba(255, 255, 255, 0.3);
  --rb-wash-fade: calc(
    var(--fs-range-zone-fade) * var(--rb-wash-fade-scale, 1)
  );
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--rb-wash-color);
}

/* Both edges are bounds — the fill has passed the ceiling, so the wash spans the whole zone. */
.rb-wash--fade-both {
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--rb-wash-color) var(--rb-wash-fade),
    var(--rb-wash-color) calc(100% - var(--rb-wash-fade)),
    transparent 100%
  );
}

/* Left edge is the floor and fades; the right is where the value stopped, and stops hard. */
.rb-wash--fade-start {
  background: linear-gradient(
    90deg,
    transparent 0%,
    var(--rb-wash-color) var(--rb-wash-fade),
    var(--rb-wash-color) 100%
  );
}

/* No floor to fade in from — a ceiling-only row is in range from the very start of the track,
   so it takes the fill's own left cap the way the flat case does. */
.rb-wash--fade-end {
  border-radius: 999px 0 0 999px;
  background: linear-gradient(
    90deg,
    var(--rb-wash-color) 0%,
    var(--rb-wash-color) calc(100% - var(--rb-wash-fade)),
    transparent 100%
  );
}

/* Where the wash ends on the fill's own end it takes the fill's cap, so it does not overhang
   the rounded terminus underneath. */
.rb-wash--cap-end {
  border-radius: 0 999px 999px 0;
}

.rb-wash--cap-both {
  border-radius: 999px;
}
