/*
    The design system's own rules, for the components the shared library renders.

    **This file exists because the studio could not see them.** Every rule here used to live in
    ScriptureJourney.App's app.css, while the components that write these class names live in
    ScriptureJourney.UI — and SJCreator links the library's stylesheets and not the App's. So inside
    the Story Studio's canvas and the Preview tab, an editor was looking at a partly unstyled player:
    .sj-visually-hidden hid nothing, so screen-reader-only text was printed on screen beside the
    thing it describes, and .sj-button rendered as a browser default button. Found at SS-7 by
    rendering the real component tree and measuring it; invisible to every test, because the elements
    were all present and correctly named.

    The rule this file keeps: **the library styles every class the library writes.** Anything an
    application invents belongs in that application's own stylesheet, and SharedStylesheetTests
    fails the build when a class the library emits has no rule here.

    Linked after tokens.css and before each application's own stylesheet, so an application can still
    override at equal specificity — which is the order these rules already had inside app.css.
*/

/*
    Visible focus everywhere (spec 17). Two rings rather than one: the white halo keeps the teal ring
    legible where focus lands on a coloured card, a photograph, or the artwork itself, which a
    single-colour outline cannot do.

    **It lived in the App's app.css until the CF-19 accessibility audit**, which is the same defect
    `components.css` was created to fix and one level more serious: every other rule in this file is
    about how a control looks, and this one is a keyboard user's entire ability to tell where they
    are. SJCreator does not link app.css, so the studio fell back to the browser's own ring
    everywhere except the five controls `creator.css` names by hand.

    A bare pseudo-class rather than a class name, which is why `SharedStylesheetTests`' general scan
    cannot see it and why it is asserted by name instead.
*/
:focus-visible {
  outline: 3px solid var(--sj-color-focus);
  outline-offset: 2px;
  box-shadow: 0 0 0 6px rgba(255, 255, 255, 0.85);
  border-radius: var(--sj-radius-sm);
}

.sj-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ----------------------------------------------------------------- page */

.sj-page {
  width: 100%;
  max-width: var(--sj-content-max);
  margin-inline: auto;
  padding: var(--sj-space-5) var(--sj-space-4)
    calc(var(--sj-space-10) + var(--sj-safe-bottom));
}

.sj-page--narrow {
  max-width: var(--sj-content-max-narrow);
}

/* A picture-first screen. The story player uses it; prose never should. */
.sj-page--wide {
  max-width: var(--sj-content-max-wide);
}

.sj-page--with-bottom-nav {
  padding-bottom: calc(
    var(--sj-bottom-nav-height) + var(--sj-space-8) + var(--sj-safe-bottom)
  );
}

/*
    A heading with one control beside it (`SJPage.TitleAction`).

    The title keeps the room and the control keeps its size: `flex: none` on the action rather than
    a width, because the speaker is a circle whose diameter is a touch target and must not be
    squeezed by a long Portuguese title. `min-width: 0` on the title is what lets it wrap instead
    of pushing the control off the edge.
*/
.sj-page__heading {
  display: flex;
  align-items: center;
  gap: var(--sj-space-3);
}

.sj-page__heading > .sj-page__title {
  flex: 1 1 auto;
  min-width: 0;
}

.sj-page__heading > :not(.sj-page__title) {
  flex: none;
  margin-block: 0;
}

.sj-page__title {
  font-size: var(--sj-text-2xl);
  font-weight: var(--sj-weight-bold);
}

.sj-page__lead {
  margin-top: var(--sj-space-2);
  color: var(--sj-color-ink-muted);
  font-size: var(--sj-text-md);
  max-width: 46ch;
}

.sj-page__content {
  margin-top: var(--sj-space-6);
}

@media (min-width: 48rem) {
  .sj-page {
    padding-inline: var(--sj-space-8);
    padding-top: var(--sj-space-8);
  }

  .sj-page__title {
    font-size: var(--sj-text-3xl);
  }
}

/*
    The App is the only thing with a bottom nav, and `SJPage` is what writes the modifier for it, so
    the rule belongs to the component rather than to the application that turns it on.
*/
@media (min-width: 64rem) {
  .sj-page--with-bottom-nav {
    padding-bottom: calc(var(--sj-space-10) + var(--sj-safe-bottom));
  }
}

/* -------------------------------------------------------- section header */

.sj-section-header {
  display: flex;
  align-items: baseline;
  gap: var(--sj-space-3);
  margin-bottom: var(--sj-space-3);
}

.sj-section-header__title {
  font-size: var(--sj-text-lg);
  font-weight: var(--sj-weight-bold);
}

.sj-section-header__description {
  color: var(--sj-color-ink-muted);
  font-size: var(--sj-text-sm);
}

.sj-section-header__action {
  margin-inline-start: auto;
}

/* --------------------------------------------------------------- buttons */

.sj-button {
  --sj-button-edge: transparent;

  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sj-space-2);
  min-height: var(--sj-touch-comfortable);
  padding: 0 var(--sj-space-6);
  border: 1px solid transparent;
  border-radius: var(--sj-radius-pill);
  font-family: inherit;
  font-size: var(--sj-text-md);
  font-weight: var(--sj-weight-bold);
  cursor: pointer;
  text-decoration: none;
  box-shadow: 0 var(--sj-lift) 0 var(--sj-button-edge);
  transition:
    background-color var(--sj-duration-fast) var(--sj-ease-standard),
    box-shadow var(--sj-duration-fast) var(--sj-ease-standard),
    transform var(--sj-duration-fast) var(--sj-ease-standard);
}

.sj-button:disabled,
.sj-button[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  box-shadow: none;
}

/*
  The press. The button travels exactly as far as its own lower edge is deep, so the shape
  appears to be pushed flat against the page rather than shrinking.
*/
.sj-button:not(:disabled):not([aria-disabled="true"]):active {
  transform: translateY(var(--sj-lift));
  box-shadow: 0 0 0 var(--sj-button-edge);
}

.sj-button--child {
  min-height: var(--sj-touch-child-primary);
  font-size: var(--sj-text-lg);
  padding-inline: var(--sj-space-8);
}

.sj-button--block {
  width: 100%;
}

.sj-button--primary {
  --sj-button-edge: #074f4e;

  background-color: var(--sj-color-primary);
  background-image: var(--sj-gradient-teal);
  color: var(--sj-color-ink-inverse);
}

.sj-button--primary:not(:disabled):hover {
  background-image: none;
  background-color: var(--sj-color-primary-hover);
}

.sj-button--secondary {
  --sj-button-edge: var(--sj-color-border-strong);

  background: var(--sj-color-surface);
  border-color: var(--sj-color-border-strong);
  color: var(--sj-color-primary);
}

.sj-button--secondary:not(:disabled):hover {
  background: var(--sj-color-primary-soft);
}

.sj-icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--sj-touch-min);
  height: var(--sj-touch-min);
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--sj-radius-pill);
  background: transparent;
  color: var(--sj-color-ink-muted);
  cursor: pointer;
  transition:
    background-color var(--sj-duration-fast) var(--sj-ease-standard),
    transform var(--sj-duration-fast) var(--sj-ease-bounce);
}

.sj-icon-button:not(:disabled):hover {
  background: var(--sj-color-surface-sunken);
  color: var(--sj-color-ink);
}

.sj-icon-button:not(:disabled):active {
  transform: scale(0.9);
}

.sj-icon-button--large {
  width: var(--sj-touch-child-primary);
  height: var(--sj-touch-child-primary);
}

.sj-icon-button--active {
  color: var(--sj-color-berry);
}

/* --------------------------------------------------- empty / loading state */

.sj-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sj-space-3);
  padding: var(--sj-space-8) var(--sj-space-4) var(--sj-space-10);
  text-align: center;
}

.sj-state__icon {
  font-size: var(--sj-text-3xl);
  line-height: 1;
}

.sj-state__scene {
  margin-bottom: var(--sj-space-2);
}

.sj-state__title {
  font-family: var(--sj-font-display);
  font-size: var(--sj-text-xl);
  font-weight: var(--sj-weight-bold);
}

.sj-state__description {
  max-width: 40ch;
  color: var(--sj-color-ink-muted);
  font-size: var(--sj-text-md);
}

.sj-loading-skeletons {
  display: flex;
  flex-direction: column;
  gap: var(--sj-space-3);
  width: 100%;
  max-width: 24rem;
}

.sj-loading-skeletons__item {
  height: 1.25rem;
}

.sj-loading-skeletons__item:first-child {
  height: 6rem;
}

.sj-skeleton {
  border-radius: var(--sj-radius-md);
  background: linear-gradient(
    90deg,
    var(--sj-color-surface-sunken) 25%,
    color-mix(in srgb, var(--sj-color-surface-sunken) 60%, white) 50%,
    var(--sj-color-surface-sunken) 75%
  );
  background-size: 200% 100%;
}

/* ------------------------------------------------------------ form actions */

.sj-form__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sj-space-3);
}

/* ------------------------------------------------------------------ glyphs */

/* The product's own control icons (SJGlyph). Sized in em so a glyph follows the font-size its
   control already sets, and filled with currentColor so on/off treatments keep working. Block,
   because an inline svg sits on the text baseline and every key centres its glyph in a flex
   column. */
.sj-glyph {
  display: block;
  width: 1.25em;
  height: 1.25em;
  fill: currentColor;
}
