/*
  Liquid glass toolbar — self-contained styles.

  One glass surface. The bar and the activity panel are not two sheets that
  slide over each other: `.liquid-glass-toolbar__shell` is the only thing with a
  backdrop filter, a rim and a shadow, and everything else changes its shape.

  State is read straight off the ARIA the component already needs — the CSS never
  waits for a class to be added. `component.js` only writes `aria-current` and
  `aria-expanded`; the search field is `:focus-within` and needs no script at all.
  Two modifiers exist as outside handles, for callers that cannot synthesise the
  event: `--open` pins the panel, `--searching` pins the search field. The index
  thumbnail needs both — an iframe with pointer events off can neither click a
  button nor put a caret in an input, and a preview that reaches in to call
  focus() steals it from the page around it.
*/

.liquid-glass-toolbar {
  /* --- geometry -------------------------------------------------------- */
  --liquid-glass-toolbar-hit: 3rem;          /* one collapsed action, square */
  --liquid-glass-toolbar-icon: 1.5rem;
  --liquid-glass-toolbar-pad: 0.375rem;        /* glass inset around the row */
  --liquid-glass-toolbar-gap: 0.1875rem;
  --liquid-glass-toolbar-split: 4.5rem;    /* between the cluster and the trailing item */
  --liquid-glass-toolbar-radius: 999px;         /* closed: a pill */
  /* Open, the surface is a card — but its corner is derived, not chosen: the
     pad plus half a pill is exactly the radius that runs concentric with the
     corner actions inside it. Closed, `999px` clamps to half the bar's height
     and lands on the same number, so the corner is the one thing that does not
     change through the morph. The height does the work. */
  --liquid-glass-toolbar-radius-open:
    calc(var(--liquid-glass-toolbar-pad) + var(--liquid-glass-toolbar-hit) / 2);
  --liquid-glass-toolbar-search-w: 14rem;
  --liquid-glass-toolbar-panel-w: 30rem;        /* a floor, not a width */
  --liquid-glass-toolbar-label-gap: 0.5625rem;

  /* the feed. Sized off the row height so the whole panel scales with one
     value, the way the bar scales off --hit. */
  --liquid-glass-toolbar-row-h: 3.5rem;
  --liquid-glass-toolbar-row-gap: 0.75rem;
  --liquid-glass-toolbar-row-radius: 1rem;
  --liquid-glass-toolbar-avatar: 2.375rem;
  --liquid-glass-toolbar-dot: 0.5rem;
  --liquid-glass-toolbar-badge: 0.4375rem;

  /* --- glass ----------------------------------------------------------- */
  /* Moss, not grey. The tint is the only thing carrying the hue: the rim, the
     sheen and the ink are all warm off-whites pulled a few points towards the
     same green, so nothing has to be re-tuned when the tint moves. */
  --liquid-glass-toolbar-tint: rgba(44, 64, 51, 0.42);
  --liquid-glass-toolbar-blur: 20px;
  --liquid-glass-toolbar-saturate: 1.55;
  --liquid-glass-toolbar-rim: rgba(224, 238, 220, 0.24);
  --liquid-glass-toolbar-sheen: rgba(232, 244, 227, 0.44);
  --liquid-glass-toolbar-drop: 0 1.5rem 3rem -1rem rgba(18, 30, 22, 0.44);

  /* the lit lozenge that travels between actions */
  --liquid-glass-toolbar-lit: rgba(222, 240, 214, 0.15);
  --liquid-glass-toolbar-lit-rim: rgba(226, 242, 218, 0.34);
  --liquid-glass-toolbar-lit-sheen: rgba(238, 249, 232, 0.5);
  --liquid-glass-toolbar-lit-lens: brightness(1.14) saturate(1.25);

  /* the same lozenge, dimmer, for a row under the pointer */
  --liquid-glass-toolbar-warm: rgba(222, 240, 214, 0.1);
  --liquid-glass-toolbar-warm-rim: rgba(226, 242, 218, 0.2);

  /* --- ink ------------------------------------------------------------- */
  --liquid-glass-toolbar-font: "Plus Jakarta Sans", system-ui, sans-serif;
  --liquid-glass-toolbar-fg: rgba(243, 249, 240, 0.97);
  --liquid-glass-toolbar-muted: rgba(226, 238, 222, 0.64);
  --liquid-glass-toolbar-dim: rgba(226, 238, 222, 0.46);
  /* Clay, across from the green. The one saturated colour in the component,
     and it is spent on the two things that mean "unread". */
  --liquid-glass-toolbar-accent: #d5793f;

  --liquid-glass-toolbar-label-size: 1rem;
  --liquid-glass-toolbar-time-size: 0.875rem;

  /* --- motion ---------------------------------------------------------- */
  /* A little past 1 on the way out: the surface arrives, settles back, stops.
     That overshoot is the whole difference between "resizes" and "liquid". */
  --liquid-glass-toolbar-morph: 460ms cubic-bezier(0.3, 1.2, 0.34, 1);
  --liquid-glass-toolbar-fade: 200ms cubic-bezier(0.4, 0, 0.2, 1);

  /* --- state, written by the one block below --------------------------- */
  --liquid-glass-toolbar-radius-now: var(--liquid-glass-toolbar-radius);
  --liquid-glass-toolbar-panel-rows: 0fr;
  --liquid-glass-toolbar-panel-width: 0px;
  --liquid-glass-toolbar-feed-opacity: 0;
  --liquid-glass-toolbar-feed-delay: 0ms;
  /* ---------------------------------------------------------------------- */

  display: flex;
  justify-content: center;
  max-width: 100%;
  font-family: var(--liquid-glass-toolbar-font);
  color: var(--liquid-glass-toolbar-fg);
}

/* The open state, declared once. Everything downstream reads these variables,
   so opening the panel is five values rather than five selectors repeated at
   every rule that cares. `--open` is the outside handle; the :has() is the
   truth, because the button's aria-expanded is what a screen reader is told. */
.liquid-glass-toolbar--open,
.liquid-glass-toolbar:has(.liquid-glass-toolbar__action--panel[aria-expanded="true"]) {
  --liquid-glass-toolbar-radius-now: var(--liquid-glass-toolbar-radius-open);
  --liquid-glass-toolbar-panel-rows: 1fr;
  --liquid-glass-toolbar-panel-width: var(--liquid-glass-toolbar-panel-w);
  --liquid-glass-toolbar-feed-opacity: 1;
  /* Declared only in the open state, so closing snaps the feed out instead of
     leaving text hanging in a box that has already collapsed. */
  --liquid-glass-toolbar-feed-delay: 140ms;
}

/* --- the surface -------------------------------------------------------- */

.liquid-glass-toolbar__shell {
  /* fit-content is what lets the surface breathe: nothing here transitions
     `width`, but an auto-width box re-measures its children every frame, so a
     label opening from 0fr drags the whole pill wider with it. */
  width: fit-content;
  max-width: 100%;

  display: grid;
  /* Not `grid-template-columns: auto`. An auto track takes the widest thing in
     it — here the panel, which asks for its floor in rem — and the percentages
     inside then resolve against that track rather than against the surface, so
     nothing is ever capped. A track that may shrink breaks the loop: it is the
     shell's own width, and the bar and the feed both squeeze into it. */
  grid-template-columns: minmax(0, 1fr);
  overflow: hidden;
  border-radius: var(--liquid-glass-toolbar-radius-now);
  background: var(--liquid-glass-toolbar-tint);

  -webkit-backdrop-filter:
    blur(var(--liquid-glass-toolbar-blur))
    saturate(var(--liquid-glass-toolbar-saturate));
  backdrop-filter:
    blur(var(--liquid-glass-toolbar-blur))
    saturate(var(--liquid-glass-toolbar-saturate));

  /* Three shadows doing three jobs: the hairline that separates glass from
     whatever is behind it, the highlight along the top edge that says the sheet
     has thickness, and the drop that lifts it off the page. */
  box-shadow:
    inset 0 0 0 1px var(--liquid-glass-toolbar-rim),
    inset 0 1px 0 0 var(--liquid-glass-toolbar-sheen),
    var(--liquid-glass-toolbar-drop);

  transition: border-radius var(--liquid-glass-toolbar-morph);
}

/* --- the row ------------------------------------------------------------ */

.liquid-glass-toolbar__bar {
  display: flex;
  align-items: center;
  gap: var(--liquid-glass-toolbar-gap);
  padding: var(--liquid-glass-toolbar-pad);
  min-width: 0;
}

/*
  The split. This bar is not five evenly spaced icons — it is a cluster of four
  and one trailing item, which is what makes a closed pill read as a toolbar
  rather than as a row of buttons. The gap is also the component's only slack:
  it is the first thing to give when the bar is squeezed, so a label opening or
  a narrow column eats into empty space before it starts clipping text.

  A pseudo-element rather than a spacer element, ordered between the two groups,
  so component.html carries no markup that exists only to hold space. Both this
  and the trailing action take `order: 1`; within one order value the box tree
  decides, and ::before is the bar's first child, so it lands between them.
*/
.liquid-glass-toolbar__bar::before {
  content: "";
  order: 1;
  /* `width`, not `flex-basis`. A flex-basis on a pseudo-element is not counted
     in the bar's max-content contribution, so the surface sized itself as if
     the gap were not there and then the gap took its space out of the labels. */
  width: var(--liquid-glass-toolbar-split);
  flex: 0 6 auto;
  min-width: 0;
}

.liquid-glass-toolbar__action--trailing {
  order: 1;
}

.liquid-glass-toolbar__action {
  /* A collapsed action is exactly --hit wide: the icon plus a pad that is half
     the difference. Square at rest, so five of them make an honest pill. */
  --liquid-glass-toolbar-action-pad: calc(
    (var(--liquid-glass-toolbar-hit) - var(--liquid-glass-toolbar-icon)) / 2
  );

  display: flex;
  align-items: center;
  flex: 0 1 auto;
  min-width: var(--liquid-glass-toolbar-hit);
  height: var(--liquid-glass-toolbar-hit);
  padding-inline: var(--liquid-glass-toolbar-action-pad);
  box-sizing: border-box;

  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--liquid-glass-toolbar-muted);

  font: inherit;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;

  transition:
    background-color var(--liquid-glass-toolbar-fade),
    box-shadow var(--liquid-glass-toolbar-fade),
    color var(--liquid-glass-toolbar-fade);
}

.liquid-glass-toolbar__action:hover {
  color: var(--liquid-glass-toolbar-fg);
}

.liquid-glass-toolbar__action:focus-visible {
  outline: 2px solid var(--liquid-glass-toolbar-fg);
  outline-offset: 2px;
}

.liquid-glass-toolbar__icon {
  position: relative;
  flex: none;
  width: var(--liquid-glass-toolbar-icon);
  height: var(--liquid-glass-toolbar-icon);
}

.liquid-glass-toolbar__icon svg {
  display: block;
  width: 100%;
  height: 100%;
}

.liquid-glass-toolbar__badge {
  position: absolute;
  top: -1px;
  right: -1px;
  width: var(--liquid-glass-toolbar-badge);
  height: var(--liquid-glass-toolbar-badge);
  border-radius: 50%;
  background: var(--liquid-glass-toolbar-accent);
}

/* --- the reveal --------------------------------------------------------- */

/*
  One mechanism, two payloads. A 0fr -> 1fr column is the only thing that
  animates; whatever sits in the track — a text label, a search input — is
  clipped to it and reaches its natural width when the track opens. Nothing here
  knows which of the two it is holding, which is why the search field and the
  nav labels move as one piece of the same surface.
*/
.liquid-glass-toolbar__reveal {
  display: grid;
  grid-template-columns: 0fr;
  min-width: 0;
  /* The track goes to zero; without this the payload keeps its own width and
     spills out of the pill instead of being clipped by it. */
  overflow: hidden;
  transition: grid-template-columns var(--liquid-glass-toolbar-morph);
}

.liquid-glass-toolbar__reveal > * {
  min-width: 0;
  /* border-box, or the padding that spaces a label off its icon survives the
     collapse as a stripe of nothing beside every square. */
  box-sizing: border-box;
  overflow: hidden;
  white-space: nowrap;
}

/*
  The search field is the one payload measured in a length rather than in `fr`.
  A text input has no max-content worth the name — its intrinsic width comes from
  the `size` attribute, not from anything CSS can set — so the track states the
  width it wants and the input fills it.
*/
.liquid-glass-toolbar__action--search .liquid-glass-toolbar__reveal {
  grid-template-columns: 0px;
}

.liquid-glass-toolbar__label {
  /* text-indent, not padding. A box cannot be narrower than its own padding, so
     a padded label collapses to an 11px stripe of nothing beside every square
     icon rather than to zero. An indent is part of the line, not part of the
     box: it disappears with the text and still counts towards the max-content
     width the open track measures. */
  text-indent: var(--liquid-glass-toolbar-label-gap);
  font-size: var(--liquid-glass-toolbar-label-size);
  font-weight: 600;
  letter-spacing: -0.005em;
  line-height: var(--liquid-glass-toolbar-hit);
}

.liquid-glass-toolbar__input {
  width: 100%;
  height: var(--liquid-glass-toolbar-hit);
  padding-inline: var(--liquid-glass-toolbar-label-gap)
    calc(var(--liquid-glass-toolbar-label-gap) * 0.375);
  border: 0;
  background: transparent;
  color: var(--liquid-glass-toolbar-fg);
  font-family: inherit;
  font-size: var(--liquid-glass-toolbar-label-size);
  font-weight: 500;
  -webkit-appearance: none;
  appearance: none;
}

.liquid-glass-toolbar__input:focus { outline: none; }

.liquid-glass-toolbar__input::placeholder {
  color: var(--liquid-glass-toolbar-dim);
}

/* --- what "selected" looks like ----------------------------------------- */

/*
  The label is not a tooltip — it is the selection indicator. Exactly one action
  carries it, and that action is the one the lozenge is under. There is no
  separate sliding element: the outgoing pill shrinks back to a square while the
  incoming one grows, and because they are adjacent in a flex row the highlight
  reads as one mass travelling rather than two fading.
*/
.liquid-glass-toolbar__action[aria-current="page"],
.liquid-glass-toolbar__action[aria-expanded="true"],
.liquid-glass-toolbar__action--search:focus-within,
.liquid-glass-toolbar--open .liquid-glass-toolbar__action--panel,
.liquid-glass-toolbar--searching .liquid-glass-toolbar__action--search {
  background: var(--liquid-glass-toolbar-lit);
  color: var(--liquid-glass-toolbar-fg);
  box-shadow:
    inset 0 0 0 1px var(--liquid-glass-toolbar-lit-rim),
    inset 0 1px 0 0 var(--liquid-glass-toolbar-lit-sheen);
  /* A second, weaker filter over glass that is already blurred: the lozenge
     reads as a thicker part of the same sheet, not as a painted-on rectangle. */
  -webkit-backdrop-filter: var(--liquid-glass-toolbar-lit-lens);
  backdrop-filter: var(--liquid-glass-toolbar-lit-lens);
}

.liquid-glass-toolbar__action[aria-current="page"] .liquid-glass-toolbar__reveal,
.liquid-glass-toolbar__action[aria-expanded="true"] .liquid-glass-toolbar__reveal,
.liquid-glass-toolbar__action--search:focus-within .liquid-glass-toolbar__reveal,
.liquid-glass-toolbar--open .liquid-glass-toolbar__action--panel .liquid-glass-toolbar__reveal,
.liquid-glass-toolbar--searching .liquid-glass-toolbar__action--search .liquid-glass-toolbar__reveal {
  grid-template-columns: 1fr;
}

.liquid-glass-toolbar__action--search:focus-within .liquid-glass-toolbar__reveal,
.liquid-glass-toolbar--searching .liquid-glass-toolbar__action--search .liquid-glass-toolbar__reveal {
  grid-template-columns: var(--liquid-glass-toolbar-search-w);
}

/*
  One expanded action at a time. Focusing the search field or opening the panel
  puts every other action back to a square, and it has to be CSS rather than the
  script, because the search field's state is :focus-within and the script never
  hears about it.
*/
.liquid-glass-toolbar__bar:has(.liquid-glass-toolbar__action--search:focus-within)
  .liquid-glass-toolbar__action:not(.liquid-glass-toolbar__action--search),
.liquid-glass-toolbar--searching .liquid-glass-toolbar__bar
  .liquid-glass-toolbar__action:not(.liquid-glass-toolbar__action--search),
.liquid-glass-toolbar--open .liquid-glass-toolbar__bar
  .liquid-glass-toolbar__action:not(.liquid-glass-toolbar__action--panel) {
  background: transparent;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.liquid-glass-toolbar__bar:has(.liquid-glass-toolbar__action--search:focus-within)
  .liquid-glass-toolbar__action:not(.liquid-glass-toolbar__action--search) .liquid-glass-toolbar__reveal,
.liquid-glass-toolbar--searching .liquid-glass-toolbar__bar
  .liquid-glass-toolbar__action:not(.liquid-glass-toolbar__action--search) .liquid-glass-toolbar__reveal,
.liquid-glass-toolbar--open .liquid-glass-toolbar__bar
  .liquid-glass-toolbar__action:not(.liquid-glass-toolbar__action--panel) .liquid-glass-toolbar__reveal {
  grid-template-columns: 0fr;
}

.liquid-glass-toolbar--open .liquid-glass-toolbar__bar
  .liquid-glass-toolbar__action--search .liquid-glass-toolbar__reveal {
  grid-template-columns: 0px;
}

/* --- the panel ---------------------------------------------------------- */

.liquid-glass-toolbar__panel {
  display: grid;
  grid-template-rows: var(--liquid-glass-toolbar-panel-rows);
  overflow: hidden;

  /*
    Three width declarations, because a closed panel still has an opinion about
    how wide the surface should be. `width` is the only one the shell measures:
    at 0 the closed pill hugs the bar, and opening animates it out to the floor
    the panel wants. The two percentages never reach intrinsic sizing at all —
    they just make the panel fill whatever the surface settled on, so a bar made
    wider than the floor by its own expanded label does not leave the feed
    sitting in a short column.
  */
  width: var(--liquid-glass-toolbar-panel-width);
  min-width: 100%;
  max-width: 100%;

  transition:
    grid-template-rows var(--liquid-glass-toolbar-morph),
    width var(--liquid-glass-toolbar-morph);
}

.liquid-glass-toolbar__feed {
  min-height: 0;
  margin: 0;
  /*
    No padding here, and that is load-bearing. This is the item of a row that
    collapses to 0fr when the panel is closed, and a box cannot be shorter than
    its own padding — so a padding-bottom survived the collapse as a strip of
    dead height inside the shell. It pushed every pill above the bar's centre
    and, because the surface was then taller than the row it wrapped, stopped
    the outer radius nesting round the inner ones. The inset is re-provided as
    margin, which does not floor a box. `overflow` is what keeps the last row's
    margin from collapsing straight back out.
  */
  padding: 0;
  overflow: hidden;
  list-style: none;
  opacity: var(--liquid-glass-toolbar-feed-opacity);
  transition: opacity var(--liquid-glass-toolbar-fade) var(--liquid-glass-toolbar-feed-delay);
}

.liquid-glass-toolbar__feed > li:last-child {
  margin-block-end: var(--liquid-glass-toolbar-pad);
}

.liquid-glass-toolbar__row {
  display: grid;
  margin-inline: var(--liquid-glass-toolbar-pad);
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--liquid-glass-toolbar-row-gap);
  min-height: var(--liquid-glass-toolbar-row-h);
  padding-inline: calc(
      (var(--liquid-glass-toolbar-row-h) - var(--liquid-glass-toolbar-avatar)) / 2
    )
    calc(var(--liquid-glass-toolbar-row-gap) * 0.9);
  border-radius: var(--liquid-glass-toolbar-row-radius);
  color: var(--liquid-glass-toolbar-muted);
  text-decoration: none;
  box-shadow: inset 0 0 0 1px transparent;
  transition:
    background-color var(--liquid-glass-toolbar-fade),
    box-shadow var(--liquid-glass-toolbar-fade);
}

.liquid-glass-toolbar__row:hover {
  background: var(--liquid-glass-toolbar-warm);
  box-shadow: inset 0 0 0 1px var(--liquid-glass-toolbar-warm-rim);
}

.liquid-glass-toolbar__row:focus-visible {
  outline: 2px solid var(--liquid-glass-toolbar-fg);
  outline-offset: -2px;
}

.liquid-glass-toolbar__avatar {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: var(--liquid-glass-toolbar-avatar);
  height: var(--liquid-glass-toolbar-avatar);
  border-radius: 50%;
  background: var(--liquid-glass-toolbar-warm);
  box-shadow: inset 0 0 0 1px var(--liquid-glass-toolbar-warm-rim);
  color: var(--liquid-glass-toolbar-fg);
}

.liquid-glass-toolbar__avatar svg {
  display: block;
  width: calc(var(--liquid-glass-toolbar-avatar) * 0.5);
  height: calc(var(--liquid-glass-toolbar-avatar) * 0.5);
}

/* Unread is a dot on the avatar, never a background on the row — the row
   background is spent on the pointer, and a list where half the rows are
   already tinted has nowhere left to show which one you are about to open. */
.liquid-glass-toolbar__row--unread .liquid-glass-toolbar__avatar::after {
  content: "";
  position: absolute;
  top: -1px;
  right: -1px;
  width: var(--liquid-glass-toolbar-dot);
  height: var(--liquid-glass-toolbar-dot);
  border-radius: 50%;
  background: var(--liquid-glass-toolbar-accent);
}

.liquid-glass-toolbar__line {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--liquid-glass-toolbar-label-size);
  line-height: 1.35;
}

.liquid-glass-toolbar__who {
  font-weight: 600;
  color: var(--liquid-glass-toolbar-fg);
}

.liquid-glass-toolbar__time {
  flex: none;
  font-size: var(--liquid-glass-toolbar-time-size);
  font-variant-numeric: tabular-nums;
  color: var(--liquid-glass-toolbar-dim);
}

/* --- no pointer to spend ------------------------------------------------ */

/*
  Almost all of this survives a phone on its own: the morph is driven by taps and
  by focus, not by hover. What does not survive is the two hover tints — the row
  under the pointer, and the icon that brightens before you commit to it. A press
  stands in for both, for as long as the finger is down.
*/
@media (hover: none) {
  .liquid-glass-toolbar__action:active {
    color: var(--liquid-glass-toolbar-fg);
  }

  .liquid-glass-toolbar__row:active {
    background: var(--liquid-glass-toolbar-warm);
    box-shadow: inset 0 0 0 1px var(--liquid-glass-toolbar-warm-rim);
  }
}

/* --- light glass -------------------------------------------------------- */

/*
  The same recipe with the tint and the ink swapped. Nothing below the variables
  changes, which is the test of whether the glass was written as a recipe or as
  a set of colours.
*/
.liquid-glass-toolbar--light {
  --liquid-glass-toolbar-tint: rgba(240, 246, 235, 0.55);
  --liquid-glass-toolbar-saturate: 1.75;
  --liquid-glass-toolbar-rim: rgba(255, 255, 255, 0.7);
  --liquid-glass-toolbar-sheen: rgba(255, 255, 255, 0.92);
  --liquid-glass-toolbar-drop: 0 1.5rem 3rem -1rem rgba(38, 48, 36, 0.26);

  --liquid-glass-toolbar-lit: rgba(252, 254, 248, 0.78);
  --liquid-glass-toolbar-lit-rim: rgba(255, 255, 255, 0.95);
  --liquid-glass-toolbar-lit-sheen: rgba(255, 255, 255, 1);
  --liquid-glass-toolbar-lit-lens: brightness(1.05) saturate(1.12);

  --liquid-glass-toolbar-warm: rgba(252, 254, 248, 0.58);
  --liquid-glass-toolbar-warm-rim: rgba(255, 255, 255, 0.82);

  --liquid-glass-toolbar-fg: #1c2a20;
  --liquid-glass-toolbar-muted: rgba(28, 42, 32, 0.62);
  --liquid-glass-toolbar-dim: rgba(28, 42, 32, 0.44);
  --liquid-glass-toolbar-accent: #b4552f;
}

/* --- reduced motion ----------------------------------------------------- */

/* The states are all still reachable; they just arrive rather than travel. */
@media (prefers-reduced-motion: reduce) {
  .liquid-glass-toolbar {
    --liquid-glass-toolbar-morph: 1ms linear;
    --liquid-glass-toolbar-fade: 1ms linear;
  }
}
