@charset "UTF-8";

/*======================================================================*
 * mxw-scm — the <mxw-scm> element's own styles.
 *
 * Loaded by the page (`<m:style href="/moxow/components/mxw-scm.css"/>`),
 * or injected as a <link> by mxw-scm.js when a page has not declared it,
 * so dropping in the script alone still works.
 *
 * In @layer mxw.scm — one sublayer per component, as mxw-back-to-top,
 * mxw-print, mxw-map, mxw-climate-chart and gallery do, so a page can
 * name a single one of them. A sublayer sorts inside `mxw`, which
 * m:head-layers puts under `theme` and `site`, so this sits exactly
 * where the bare `mxw` it used to name sat.
 *
 * Being in a layer at all is the point. Unlayered styles beat every
 * layered one, so the old comment on these component sheets — "light
 * DOM, the page's own CSS overrides this" — was only true for properties
 * the component never set: a page rule in @layer components could not
 * touch a box-shadow declared outside a layer.
 *======================================================================*/

@layer mxw.scm {
  /* min-inline-size:0 so the element can be laid out anywhere. As a flex
     item its automatic minimum is min-content, and the description below
     is a single nowrap run — which made that min-content the width of
     the whole sentence and punched the box straight through its
     container. */
  mxw-scm {
    display: block;
    min-inline-size: 0;
  }

  /* The paper box the CITI block sits in. Its mixin is border 1px
     rgba(0,0,0,.3) + shadow 0 2px 6px rgba(0,0,0,.3) on white — the same
     values this site already carries as --paper-*, so the tokens are
     used where they exist.

     More room at the sides than at top and bottom: the box is wide and
     shallow, and its content runs to the inline edges (the keys on one
     side, the counts on the other), so the same .5ex all round left both
     of them almost touching the border. */
  mxw-scm > details {
    padding-block: .5ex;
    padding-inline: 1.5ex;
    background: #fff;
    border: var(--paper-border, 1px solid rgb(0 0 0 / .3));
    box-shadow: var(--paper-shadow, 0 2px 6px rgb(0 0 0 / .3));
  }

  /*-- The marks -----------------------------------------------------*
     Which mark a span carries is data (data-mark, data-flavor, set by
     the script); what it looks like is here. They were written onto the
     elements as inline `style.mask` strings, where no page could
     restyle them and no sheet could see them.

     Masks rather than images: the glyph takes currentColor, so it
     follows the ink it sits in — and the flavour icons bring their own
     brand colour as a token a page can override. */
  .mxw-scm-mark[data-mark="branches"],
  .mxw-scm-icon[data-mark="branches"] { mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='6' cy='5' r='2.5'/%3E%3Ccircle cx='6' cy='19' r='2.5'/%3E%3Ccircle cx='18' cy='9' r='2.5'/%3E%3Cpath d='M6 7.5v9M18 11.5c0 3-4 3-6 5'/%3E%3C/svg%3E") center / contain no-repeat; }
  .mxw-scm-mark[data-mark="tags"],
  .mxw-scm-icon[data-mark="tags"] { mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 12V4h8l9 9-8 8-9-9z'/%3E%3Ccircle cx='7.5' cy='7.5' r='1.2'/%3E%3C/svg%3E") center / contain no-repeat; }
  .mxw-scm-mark[data-mark="releases"],
  .mxw-scm-icon[data-mark="releases"] { mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v11m0 0l-4.5-4.5M12 14l4.5-4.5M4 19h16'/%3E%3C/svg%3E") center / contain no-repeat; }
  .mxw-scm-mark[data-mark="date"],
  .mxw-scm-icon[data-mark="date"] { mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M3 10h18M8 3v4M16 3v4'/%3E%3C/svg%3E") center / contain no-repeat; }
  .mxw-scm-mark[data-mark="author"],
  .mxw-scm-icon[data-mark="author"] { mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='8' r='3.5'/%3E%3Cpath d='M5 20c0-3.9 3.1-6 7-6s7 2.1 7 6'/%3E%3C/svg%3E") center / contain no-repeat; }
  .mxw-scm-mark[data-mark="message"],
  .mxw-scm-icon[data-mark="message"] { mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512' fill='black'%3E%3Cpath d='M311.4 32l8.6 0c35.3 0 64 28.7 64 64l0 352c0 35.3-28.7 64-64 64L64 512c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l8.6 0C83.6 12.9 104.3 0 128 0L256 0c23.7 0 44.4 12.9 55.4 32zM248 112c13.3 0 24-10.7 24-24s-10.7-24-24-24L136 64c-13.3 0-24 10.7-24 24s10.7 24 24 24l112 0zM128 256a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm32 0c0 13.3 10.7 24 24 24l112 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-112 0c-13.3 0-24 10.7-24 24zm0 128c0 13.3 10.7 24 24 24l112 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-112 0c-13.3 0-24 10.7-24 24zM96 416a32 32 0 1 0 0-64 32 32 0 1 0 0 64z'/%3E%3C/svg%3E") center / contain no-repeat; }
  .mxw-scm-mark[data-mark="link"],
  .mxw-scm-icon[data-mark="link"] { mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='black'%3E%3Cpath d='M307.8 18.4c-12 5-19.8 16.6-19.8 29.6l0 80-112 0c-97.2 0-176 78.8-176 176 0 113.3 81.5 163.9 100.2 174.1 2.5 1.4 5.3 1.9 8.1 1.9 10.9 0 19.7-8.9 19.7-19.7 0-7.5-4.3-14.4-9.8-19.5-9.4-8.8-22.2-26.4-22.2-56.7 0-53 43-96 96-96l96 0 0 80c0 12.9 7.8 24.6 19.8 29.6s25.7 2.2 34.9-6.9l160-160c12.5-12.5 12.5-32.8 0-45.3l-160-160c-9.2-9.2-22.9-11.9-34.9-6.9z'/%3E%3C/svg%3E") center / contain no-repeat; }

  .mxw-scm-icon[data-flavor="gitlab"] {
    --mxw-scm-brand: #fc6d26;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='black'%3E%3Cpath d='M504 204.6l-.7-1.8-69.7-181.8c-1.4-3.6-3.9-6.6-7.2-8.6-2.4-1.6-5.1-2.5-8-2.8s-5.7 .1-8.4 1.1-5.1 2.7-7.1 4.8c-1.9 2.1-3.3 4.7-4.1 7.4l-47 144-190.5 0-47.1-144c-.8-2.8-2.2-5.3-4.1-7.4-2-2.1-4.4-3.7-7.1-4.8-2.6-1-5.5-1.4-8.4-1.1s-5.6 1.2-8 2.8c-3.2 2-5.8 5.1-7.2 8.6L9.8 202.8 9 204.6c-10 26.2-11.3 55-3.5 82 7.7 26.9 24 50.7 46.4 67.6l.3 .2 .6 .4 106 79.5c38.5 29.1 66.7 50.3 84.6 63.9 3.7 1.9 8.3 4.3 13 4.3s9.3-2.4 13-4.3c17.9-13.5 46.1-34.9 84.6-63.9l106.7-79.9 .3-.3c22.4-16.9 38.7-40.6 45.6-67.5 8.6-27 7.4-55.8-2.6-82z'/%3E%3C/svg%3E") center / contain no-repeat;
  }
  .mxw-scm-icon[data-flavor="github"] {
    --mxw-scm-brand: #181717;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' fill='black'%3E%3Cpath d='M216.5 362.5c-66-8-112.5-55.5-112.5-117 0-25 9-52 24-70-6.5-16.5-5.5-51.5 2-66 20-2.5 47 8 63 22.5 19-6 39-9 63.5-9s44.5 3 62.5 8.5c15.5-14 43-24.5 63-22 7 13.5 8 48.5 1.5 65.5 16 19 24.5 44.5 24.5 70.5 0 61.5-46.5 108-113.5 116.5 17 11 28.5 35 28.5 62.5l0 52C323 491.5 335.5 500 350.5 494 441 459.5 512 369 512 257 512 115.5 397 0 255.5 0S0 115.5 0 257c0 111 70.5 203 165.5 237.5 13.5 5 26.5-4 26.5-17.5l0-40c-7 3-16 5-24 5-33 0-52.5-18-66.5-51.5-5.5-13.5-11.5-21.5-23-23-6-.5-8-3-8-6 0-6 10-10.5 20-10.5 14.5 0 27 9 40 27.5 10 14.5 20.5 21 33 21s20.5-4.5 32-16c8.5-8.5 15-16 21-21z'/%3E%3C/svg%3E") center / contain no-repeat;
  }
  .mxw-scm-icon[data-flavor="git"] {
    --mxw-scm-brand: #f05032;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' fill='black'%3E%3Cpath d='M439.6 236.1L244 40.5C238.6 35 231.2 32 223.6 32s-15 3-20.4 8.4l-40.7 40.6 51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3l-46.3-46.3 0 121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56l0-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4L204.1 471.6c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4L439.6 276.9c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4z'/%3E%3C/svg%3E") center / contain no-repeat;
  }

  /* No caret: the CITI design hides the disclosure triangle and gives
     its job to the flavor mark, which is why that mark is a mask (it
     cannot go missing) and why it gets the pointer cursor and the hover
     pulse. The open state is told by the body appearing beside its
     rule. */
  mxw-scm > details > summary {
    display: flex;
    align-items: center;
    gap: 1ex;
    min-block-size: var(--target, 1.75rem);
    cursor: pointer;
    list-style: none;
  }

  mxw-scm > details > summary::-webkit-details-marker { display: none; }

  mxw-scm .mxw-scm-icon {
    flex: none;
    inline-size: 2ex;
    block-size: 2ex;
    cursor: pointer;
    background-color: currentColor;
  }

  mxw-scm .mxw-scm-name {
    flex: none;
    font-weight: 700;
    white-space: nowrap;
  }

  /* One line, cut with an ellipsis when the row runs out of width.
     min-inline-size:0 is what makes that possible at all: a flex item
     will not shrink below its min-content size without it, so the
     description would push the counts off the end instead of being
     clipped. It is the only item allowed to shrink — the name, the mark
     and the counts all keep their size. */
  mxw-scm .mxw-scm-desc {
    flex: 0 1 auto;
    min-inline-size: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: var(--color-meta, #6a6a6a);
  }

  mxw-scm .mxw-scm-desc:empty { display: none; }

  mxw-scm .mxw-scm-spacer { flex: 1 1 auto; }

  mxw-scm .mxw-scm-count {
    display: none;
    align-items: center;
    gap: .4ex;
    font-size: .8125rem;
    color: var(--color-meta, #6a6a6a);
  }

  mxw-scm .mxw-scm-count.is-set { display: inline-flex; }

  mxw-scm .mxw-scm-mark {
    flex: none;
    inline-size: 1em;
    block-size: 1em;
    background-color: currentColor;
  }

  /* Open: the CITI left rule. grey (#808080) reads at 3.9:1 on white;
     --color-rule at #ccc would be all but invisible as a spine.

     The rule hangs from the flavor mark, so it is centred under it
     rather than merely indented: the mark is 2ex wide and starts at the
     content edge, so its axis is at 1ex, and the 3px rule has to start
     half its own width before that. (The original's flat 1ex margin put
     the rule's left edge on that axis, so it read as offset from the
     icon it descends from.)

     Two real tracks, the first sized by the longest key. A flex-basis on
     the legend cannot do this: it is a guess at the width of a word, and
     the moment the guess is short the item's automatic minimum floors it
     at min-content and that one row pushes out of line. "BRANCHES" needs
     about 64px; the 10ex basis it had resolved against the legend's OWN
     0.75rem font, so it was only ~54px, and branches alone sat wrong. */
  mxw-scm > details[open] > .mxw-scm-body {
    margin-inline-start: calc(1ex - 1.5px);
    padding-inline-start: calc(1ex + 1.5px);
    padding-block: .5ex 0;
    border-inline-start: 3px solid var(--rule-strong, #8a8a8a);
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: .35ex 1.5ex;
    align-items: baseline;
  }

  /* The section is a grouping in the markup, not a box: display:contents
     drops it so its legend and its list become items of the body grid
     above and share its columns. Without it each section would be its
     own formatting context and the columns could not line up across them
     at all. */
  mxw-scm .mxw-scm-section { display: contents; }

  /* [hidden] is a UA `display:none`, and the author `display:contents`
     above beats it — so an empty section would stay visible without
     this. The usual trap with hidden on anything given a display. */
  mxw-scm .mxw-scm-section[hidden] { display: none; }

  /* The hanging label, as a real element rather than ::before content:
     "Branches" is meaning, and meaning does not belong in a
     pseudo-element where assistive tech and translation cannot reach it.

     The legend is furniture, so it is set as furniture: the small
     uppercase grey label this site already uses for .mxw-colophon h2 and
     its status chips. Bold black competed with the values, which are the
     thing worth reading.

     Right-aligned: the keys are ragged words of very different lengths
     (COMMIT, BRANCHES), so flushing them against the values puts a clean
     edge where the eye actually travels — from the key into its row —
     instead of leaving a gutter that widens and narrows. */
  mxw-scm .mxw-scm-legend {
    font-size: .75rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
    text-align: end;
    color: var(--color-meta, #6a6a6a);
  }

  mxw-scm .mxw-scm-list {
    min-inline-size: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: .5ex;
  }

  /* Values are a run of links, not boxed chips. A tag is a word; a box
     around every word turns four tags into four objects to parse, and
     this block sits under a project description where it is the
     secondary thing on the card.

     :not(), because "none" and the loading and error lines are prose,
     not values — they take neither the underline nor a separator. */
  mxw-scm .mxw-scm-values > li:not(.mxw-scm-loading, .mxw-scm-error) { display: inline; }

  /* Separator between siblings only, so there is no trailing dot.
     Decorative, hence a pseudo-element: it carries no meaning that a
     screen reader needs.

     Releases run on with the same middot as tags and branches. They
     carry a date each, which is why they used to stack; the separator is
     what makes that work in a row, marking where one release ends and
     the next begins so "v1.0.0 Mar 30, 2024" reads as one thing. */
  mxw-scm .mxw-scm-values > li + li:not(.mxw-scm-loading, .mxw-scm-error)::before {
    content: "\00B7";
    margin-inline-end: .25ex;
    color: var(--rule-strong, #8a8a8a);
  }

  /* padding-block does not grow an inline box's line, but it DOES grow
     what the pointer can hit — so the run stays as tight as it looks
     while each link clears the 24px target floor. Measured: the glyph
     box is ~14px, so .32rem top and bottom takes it to 24.2. */
  mxw-scm .mxw-scm-value {
    text-decoration: underline;
    text-underline-offset: .15em;
    padding-block: .32rem;
  }

  /* Spread-only shadow in the same colour, so the mark sits a little
     outside the glyph box instead of hugging it. Padding cannot do this
     job here: the value already carries .32rem of it for the target
     size, and more would move the row. 2px rather than the 3px
     default.css uses — the rows in this grid are .35ex apart, and 3px
     would have two marks touching. */
  mxw-scm .mxw-scm-value:hover {
    color: var(--color-hover-ink, #500000);
    background: var(--color-hover-surface, #f2d015);
    border-radius: 3px;
    box-shadow: 0 0 0 2px var(--color-hover-surface, #f2d015);
    box-decoration-break: clone;
  }

  /* nowrap on the date so a release is never split across two lines from
     the middle of its own date. */
  mxw-scm .mxw-scm-date {
    margin-inline-start: .4ex;
    font-size: .8125rem;
    color: var(--color-meta, #6a6a6a);
    white-space: nowrap;
  }

  /* Commit is the one row whose value is more than a line, and a
     baseline taken from a two-line block drops the key half way down it.
     Aligned to the top instead, so the key sits against the subject it
     names rather than floating between subject and meta. The single-line
     rows keep the baseline alignment, which is what seats their small
     caps correctly. */
  mxw-scm .mxw-scm-commit .mxw-scm-legend { align-self: start; }

  mxw-scm .mxw-scm-commit .mxw-scm-list { display: block; }

  /* The commit line: the permalink on the left spanning both rows, the
     subject above, date and author below — the original's
     "link message message" / "link date author" grid. */
  mxw-scm .mxw-scm-commit li {
    display: grid;
    gap: 2px .5ex;
    grid-template-columns: auto 1fr;
    grid-template-areas: "link message"
                         "link meta";
  }

  /* align-self:start — the permalink spans both rows, so left to stretch
     it centres itself between the subject and the meta line instead of
     sitting beside the subject it belongs to. */
  mxw-scm .mxw-scm-permalink {
    grid-area: link;
    align-self: start;
    display: flex;
    align-items: center;
    justify-content: center;
    min-inline-size: var(--target-min, 1.5rem);
    min-block-size: var(--target-min, 1.5rem);
  }

  mxw-scm .mxw-scm-permalink .mxw-scm-mark {
    inline-size: 1.1em;
    block-size: 1.1em;
  }

  mxw-scm .mxw-scm-subject { grid-area: message; }

  /* The subject's mark sits IN the text flow, inline-block rather than a
     flex item: a subject long enough to wrap should wrap as one
     paragraph under its glyph, which is what the original's ::before
     did. (The date and author beside it are short, so those stay
     inline-flex rows.) */
  mxw-scm .mxw-scm-subject .mxw-scm-mark {
    display: inline-block;
    vertical-align: -.12em;
    margin-inline-end: .5ex;
  }

  mxw-scm .mxw-scm-meta {
    grid-area: meta;
    display: flex;
    flex-wrap: wrap;
    gap: .25ex 1ex;
    font-size: .8125rem;
    color: var(--color-meta, #6a6a6a);
  }

  mxw-scm .mxw-scm-field {
    display: inline-flex;
    align-items: center;
    gap: .4ex;
  }

  mxw-scm .mxw-scm-loading,
  mxw-scm .mxw-scm-error {
    color: var(--color-meta, #6a6a6a);
    font-style: italic;
  }

  /* Heard but not seen: the counts are a mark and a number, so the word
     they count lives here. */
  mxw-scm .mxw-scm-sr {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* Hovered, the mark takes its forge's own colour. Outside the
     reduced-motion query on purpose: the colour is the feedback, and a
     reader who has asked for less movement should still get it. The
     pulse below only adds the movement. */
  mxw-scm > details > summary:hover .mxw-scm-icon {
    background-color: var(--mxw-scm-brand, currentColor);
  }

  @media (prefers-reduced-motion: no-preference) {
    mxw-scm > details > summary:hover .mxw-scm-icon {
      animation: mxw-scm-pulse 2s infinite;
    }

    @keyframes mxw-scm-pulse {
      0%   { scale: 1; }
      70%  { scale: 1.4; }
      100% { scale: 1; }
    }
  }
}
