/*
 * THE TYPE RAMP, APPLIED. Every value here is a token — `tokens.css` owns the
 * two curves and the 768px breakpoint, so this sheet has no media query and no
 * second copy of a number. `type_ramp.ts` measures the same values in JS and
 * `tokens_agreement.test.ts` holds the two together.
 *
 * `display: inline` is deliberate: a run of text is inline-level, and a flex or
 * grid parent blockifies it anyway — which is what makes `width` and `flex` on a
 * Text work wherever they already did.
 *
 * `white-space: pre-wrap` keeps a newline inside a string a line break, so data
 * that arrives with `\n` reads the way it was written.
 */
@layer theme, base, lotics, components, utilities;
@layer lotics.tokens, lotics.reset, lotics.components;

@layer lotics.components {
  .lotics-text {
    display: inline;
    font-family: var(--font-sans);
    font-size: var(--lotics-text-sm);
    line-height: var(--lotics-leading-sm);
    letter-spacing: var(--lotics-tracking-sm);
    font-weight: var(--lotics-weight-regular);
    color: var(--lotics-ink-default);
    text-align: start;
    text-decoration: none;
    text-transform: none;
    white-space: pre-wrap;
    overflow-wrap: break-word;
    font-feature-settings: var(--lotics-font-features);
    /* A run of text is not a control, but the ELEMENT under it may be. Everything
       a UA would paint on one is stated here, so a `render` substitution changes
       the semantics and nothing else. `cursor` is the exception — it follows the
       element. */
    background: none;
    border: 0 solid var(--border);
    border-radius: 0;
    appearance: none;
  }

  .lotics-text:focus-visible {
    outline: var(--lotics-ring-width) solid var(--ring);
    outline-offset: 0;
  }

  /* A run that RESPONDS points at itself, and what decides that is the ELEMENT
     rather than a prop. */
  button.lotics-text,
  a.lotics-text[href] {
    cursor: pointer;
  }

  .lotics-text[data-size="xs"] {
    font-size: var(--lotics-text-xs);
    line-height: var(--lotics-leading-xs);
    letter-spacing: var(--lotics-tracking-xs);
  }
  .lotics-text[data-size="sm"] {
    font-size: var(--lotics-text-sm);
    line-height: var(--lotics-leading-sm);
    letter-spacing: var(--lotics-tracking-sm);
  }
  .lotics-text[data-size="md"] {
    font-size: var(--lotics-text-md);
    line-height: var(--lotics-leading-md);
    letter-spacing: var(--lotics-tracking-md);
  }
  .lotics-text[data-size="lg"] {
    font-size: var(--lotics-text-lg);
    line-height: var(--lotics-leading-lg);
    letter-spacing: var(--lotics-tracking-lg);
  }
  /* Display ramp — the heading ladder: xl = `##` (section), xxl = `#`
     (page/record title), xxxl = hero numbers. */
  .lotics-text[data-size="xl"] {
    font-size: var(--lotics-text-xl);
    line-height: var(--lotics-leading-xl);
    letter-spacing: var(--lotics-tracking-xl);
  }
  .lotics-text[data-size="xxl"] {
    font-size: var(--lotics-text-xxl);
    line-height: var(--lotics-leading-xxl);
    letter-spacing: var(--lotics-tracking-xxl);
  }
  .lotics-text[data-size="xxxl"] {
    font-size: var(--lotics-text-xxxl);
    line-height: var(--lotics-leading-xxxl);
    letter-spacing: var(--lotics-tracking-xxxl);
  }

  /* TIGHT — a stacked pair, not prose. A rung already at or below `size + 6`
     resolves to its own prose leading, so every rung can carry a rule. */
  .lotics-text[data-leading="tight"][data-size="xs"] {
    line-height: var(--lotics-leading-tight-xs);
  }
  .lotics-text[data-leading="tight"][data-size="sm"] {
    line-height: var(--lotics-leading-tight-sm);
  }
  .lotics-text[data-leading="tight"][data-size="md"] {
    line-height: var(--lotics-leading-tight-md);
  }
  .lotics-text[data-leading="tight"][data-size="lg"] {
    line-height: var(--lotics-leading-tight-lg);
  }
  .lotics-text[data-leading="tight"][data-size="xl"] {
    line-height: var(--lotics-leading-tight-xl);
  }
  .lotics-text[data-leading="tight"][data-size="xxl"] {
    line-height: var(--lotics-leading-tight-xxl);
  }
  .lotics-text[data-leading="tight"][data-size="xxxl"] {
    line-height: var(--lotics-leading-tight-xxxl);
  }

  /* An id, a URL, a hash — a token with nowhere to break. `break-word` only
     breaks a word that would overflow ALONE. Opt-in: prose set this way breaks
     mid-word wherever the line happens to end. */
  .lotics-text[data-wrap="anywhere"] {
    overflow-wrap: anywhere;
  }

  .lotics-text[data-weight="regular"] {
    font-weight: var(--lotics-weight-regular);
  }
  .lotics-text[data-weight="medium"] {
    font-weight: var(--lotics-weight-medium);
  }
  .lotics-text[data-weight="semibold"] {
    font-weight: var(--lotics-weight-semibold);
  }

  .lotics-text[data-color="default"] {
    color: var(--lotics-ink-default);
  }
  .lotics-text[data-color="muted"] {
    color: var(--lotics-ink-muted);
  }
  .lotics-text[data-color="inactive"] {
    color: var(--lotics-ink-inactive);
  }
  .lotics-text[data-color="onInverse"] {
    color: var(--lotics-ink-on-inverse);
  }
  .lotics-text[data-color="danger"] {
    color: var(--lotics-ink-danger);
  }
  .lotics-text[data-color="warning"] {
    color: var(--lotics-ink-warning);
  }
  .lotics-text[data-color="success"] {
    color: var(--lotics-ink-success);
  }

  .lotics-text[data-family="display"] {
    font-family: var(--lotics-font-display);
  }

  .lotics-text[data-align="left"] {
    text-align: left;
  }
  .lotics-text[data-align="center"] {
    text-align: center;
  }
  .lotics-text[data-align="right"] {
    text-align: right;
  }

  .lotics-text[data-decoration="underline"] {
    text-decoration: underline;
  }
  .lotics-text[data-decoration="line-through"] {
    text-decoration: line-through;
  }
  .lotics-text[data-decoration="underline line-through"] {
    text-decoration: underline line-through;
  }

  .lotics-text[data-transform="uppercase"] {
    text-transform: uppercase;
    /* Uppercase needs positive tracking to read as designed, not shouted — the
       one place the ramp's own curve is wrong, being drawn for lowercase. */
    letter-spacing: var(--lotics-tracking-caps);
  }
  .lotics-text[data-transform="lowercase"] {
    text-transform: lowercase;
  }
  .lotics-text[data-transform="capitalize"] {
    text-transform: capitalize;
  }

  /* Only when ASKED for: left to inherit, each run takes its container's answer,
     which is what a container setting `user-select` is trying to say. */
  .lotics-text[data-select="none"] {
    user-select: none;
  }
  .lotics-text[data-select="auto"] {
    user-select: auto;
  }
  .lotics-text[data-select="text"] {
    user-select: text;
  }

  /*
   * A CLAMP NEEDS A FLOOR: without `min-width: 0` a clamped run in a flex row
   * floors at its own min-content width and runs off the frame. Only with the
   * clamp — an unclamped run's min-content width is what keeps its longest word
   * inside the box.
   */
  .lotics-text[data-clamped] {
    min-width: 0;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: var(--lotics-text-lines);
    line-clamp: var(--lotics-text-lines);
    overflow: hidden;
  }
}
