/* A surface of its own, because it is a different object.
 *
 * Measured on the live site: the frame's background was byte for byte the
 * page's - both oklch(0.18 0.01 264) in dark - with no shadow, so the only
 * thing marking where the component begins was a hairline at 1.35:1 against
 * the 3:1 a boundary needs. On a cheap monitor or in bright light it is gone,
 * and with it the whole point of drawing the card rather than describing it.
 *
 * A sunken ground with the card sitting on it, rather than a heavier border:
 * the surround is the existing quiet token, the card keeps paper, and the
 * difference is a ring of colour rather than a line somebody has to see. */
.cardframe {
  --ds-surface: var(--paper);
  --ds-surface-sunken: var(--quiet);
  --ds-background-neutral: var(--quiet);
  --ds-background-neutral-hovered: var(--quiet);
  --ds-text: var(--ink);
  --ds-text-subtle: var(--dim);
  --ds-text-subtlest: var(--dim);
  --ds-link: var(--link);
  --ds-border: var(--line);
  --ds-border-bold: var(--dim);
  --ds-border-focused: var(--link);
  --ds-font-family-body: var(--sans);

  /* The accents, which are not decoration. The filled square in the streak
     strip is magenta-bolder, the bar's segments are the blue and purple
     subtles, and the green is the one positive colour the card allows -
     something a person fixed. Undefined, they came out as empty outlines and
     colourless segments, which is a different card: the strip showing two
     findings in ten mornings showed none. Atlassian's own values, so the
     demonstration is the product's palette rather than an impression of it. */
  --ds-background-accent-magenta-bolder: light-dark(#943D73, #E774BB);
  --ds-background-accent-orange-bolder: light-dark(#A54800, #FEA362);
  --ds-background-accent-blue-subtle: #579DFF;
  --ds-background-accent-purple-subtle: #9F8FEF;
  --ds-background-accent-gray-subtle: light-dark(rgba(23,43,77,.4), rgba(255,255,255,.35));
  --ds-text-accent-green: light-dark(#216E4E, #7EE2B8);

  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 1.1rem 1.2rem;
  background: var(--paper);
  font-size: .92rem;
}
/* The card keeps its own measure. Overriding it here made the demonstration
   wider than anything the product ever draws, on a page whose caption says it
   is drawn by the gadget rather than pictured. */

/* A key that looks like the link it is on a real card, and says so instead of
   going anywhere. The hint is a pseudo-element, so it costs no script and no
   markup, and it appears on hover.
   
   Only on hover: this is a span, deliberately outside the tab order for the
   same reason the card's dead buttons are, so the :focus-visible rule beside
   it can never fire. The comment here used to claim keyboard focus worked,
   which is the kind of sentence this site exists to not have. What a reader
   without a mouse gets instead is the caption under the card, which says the
   keys do not open from here - and it says so on every page that draws one
   now, rather than only on the front page. The duplicate title attribute that
   used to sit beside this is gone: it carried the same sentence and drew a
   second tooltip over the first.

   No backticks in this comment, and none in any comment inside this
   stylesheet: the whole sheet is a template literal, so one closes it and the
   build stops on whatever word came next. Twice in five minutes. */
/* The cursor no longer promises what a phone cannot deliver.
 *
 * The help cursor says there is an explanation behind this, and the explanation is a
 * hover tooltip - which on a touch screen does not exist. The keys keep their
 * appearance, because the card is meant to be the product rather than a
 * drawing of it and in the product they are links; what changes is that the
 * sentence saying they do not open here is now under every card rather than
 * under one of three. */
.cardframe .mock { color: var(--link); text-decoration: underline dotted;
                   text-underline-offset: .18em; cursor: default }
/* The hint measures itself against the line the link sits on, not the link.
 *
 * An absolutely positioned box with left: 0 and no width of its own shrinks to
 * the space its containing block offers. While that block was the link itself,
 * 44 to 84 pixels of it, the hint came out roughly a word per line - 54 by 173
 * over "see all 4", 84 by 90 over a column name - and the max-width below was
 * a ceiling it never came near. Giving it max-content instead runs it 140px off
 * the right of the card at 375px, which is what that ceiling is there to stop.
 * The row is wide enough for the sentence at both widths and keeps it inside
 * the card at both: at 375px it is 222 by 21, ending 85px short of the edge.
 *
 * What this costs: the hint aligns to the left of the row rather than sitting
 * under the word hovered. Every link in a row carries the same sentence in
 * kind, so the sentence still answers the thing it appeared for. */
.cardframe .keys, .cardframe .still { position: relative }
.cardframe .mock:hover::after {
  content: attr(data-hint); position: absolute; left: 0; top: calc(100% + .4rem);
  max-width: min(16rem, 70vw); background: var(--ink); color: var(--paper);
  padding: .25rem .5rem; border-radius: 4px; font-size: .78rem;
  font-family: var(--sans); z-index: 2; pointer-events: none;
}
/* The state switcher. Seven radios, seven labels, seven panels, and the
   panel a radio shows is the one at its own place in the list - which is why
   the inputs sit before both rows rather than beside their labels. */
.states { border: 0; margin: 0 0 1.15rem; padding: 0; min-width: 0 }
/* The eight panels are 115 to 770 pixels tall, so switching chips moved
   everything below by up to 655 and the reader had to find their place again.
   A floor rather than a fixed height: the tallest still grows. */
.statepanels { min-height: 38rem }
@media (max-width: 46rem) { .statepanels { min-height: 0 } }
.states legend { padding: 0; font-size: .9rem; color: var(--dim); margin-bottom: .6rem }
.statepick { position: absolute; width: 1px; height: 1px; overflow: hidden;
             clip-path: inset(50%); white-space: nowrap }
.statetabs { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: 1rem }
.statetabs label { border: 1px solid var(--line); border-radius: 999px;
                   padding: .3rem .75rem; font-size: .85rem; color: var(--dim);
                   cursor: pointer; background: var(--paper) }
.statetabs label:hover { color: var(--ink) }
/* Two signals for the chosen one, because a border colour alone says nothing
   to a reader who cannot separate the two. */
.statepanel { display: none }
#cs-0:checked ~ .statetabs label[for="cs-0"] {
  color: var(--paper); background: var(--ink); border-color: var(--ink);
  font-weight: 600 }
#cs-0:focus-visible ~ .statetabs label[for="cs-0"] {
  outline: 2px solid var(--link); outline-offset: 3px }
#cs-0:checked ~ .statepanels > .statepanel:nth-child(1) { display: block }
#cs-1:checked ~ .statetabs label[for="cs-1"] {
  color: var(--paper); background: var(--ink); border-color: var(--ink);
  font-weight: 600 }
#cs-1:focus-visible ~ .statetabs label[for="cs-1"] {
  outline: 2px solid var(--link); outline-offset: 3px }
#cs-1:checked ~ .statepanels > .statepanel:nth-child(2) { display: block }
#cs-2:checked ~ .statetabs label[for="cs-2"] {
  color: var(--paper); background: var(--ink); border-color: var(--ink);
  font-weight: 600 }
#cs-2:focus-visible ~ .statetabs label[for="cs-2"] {
  outline: 2px solid var(--link); outline-offset: 3px }
#cs-2:checked ~ .statepanels > .statepanel:nth-child(3) { display: block }
#cs-3:checked ~ .statetabs label[for="cs-3"] {
  color: var(--paper); background: var(--ink); border-color: var(--ink);
  font-weight: 600 }
#cs-3:focus-visible ~ .statetabs label[for="cs-3"] {
  outline: 2px solid var(--link); outline-offset: 3px }
#cs-3:checked ~ .statepanels > .statepanel:nth-child(4) { display: block }
#cs-4:checked ~ .statetabs label[for="cs-4"] {
  color: var(--paper); background: var(--ink); border-color: var(--ink);
  font-weight: 600 }
#cs-4:focus-visible ~ .statetabs label[for="cs-4"] {
  outline: 2px solid var(--link); outline-offset: 3px }
#cs-4:checked ~ .statepanels > .statepanel:nth-child(5) { display: block }
#cs-5:checked ~ .statetabs label[for="cs-5"] {
  color: var(--paper); background: var(--ink); border-color: var(--ink);
  font-weight: 600 }
#cs-5:focus-visible ~ .statetabs label[for="cs-5"] {
  outline: 2px solid var(--link); outline-offset: 3px }
#cs-5:checked ~ .statepanels > .statepanel:nth-child(6) { display: block }
#cs-6:checked ~ .statetabs label[for="cs-6"] {
  color: var(--paper); background: var(--ink); border-color: var(--ink);
  font-weight: 600 }
#cs-6:focus-visible ~ .statetabs label[for="cs-6"] {
  outline: 2px solid var(--link); outline-offset: 3px }
#cs-6:checked ~ .statepanels > .statepanel:nth-child(7) { display: block }
#cs-7:checked ~ .statetabs label[for="cs-7"] {
  color: var(--paper); background: var(--ink); border-color: var(--ink);
  font-weight: 600 }
#cs-7:focus-visible ~ .statetabs label[for="cs-7"] {
  outline: 2px solid var(--link); outline-offset: 3px }
#cs-7:checked ~ .statepanels > .statepanel:nth-child(8) { display: block }
.cardframe .keysep { display: none }
/* Not on the button the card marks spent. The product sets cursor: default
   there and explains why beside it - the cursor says the press will not do the
   usual thing - and this rule, one class heavier, was quietly winning. A
   demonstration that teaches a behaviour the product does not have is the one
   thing a page showing real markup is for. */
.cardframe button[data-copy]:not([aria-disabled='true']) { cursor: pointer }
/*
 * The block's own look, built on Atlassian's design tokens.
 *
 * The decision (OUT-42): tokens for colour and spacing, our own layout on top.
 * Not the component library, because none of what OUT-18 decided exists in it —
 * one large number, a drawn proportion, a norm rail — and assembling those out
 * of components meant for dense admin screens costs bundle weight to end up
 * fighting the vocabulary anyway. Not our own palette either, because dark mode
 * is not optional and `var(--ds-*)` gets it right in every theme Atlassian ever
 * ships, including ones that do not exist yet.
 *
 * Every colour here is a token. A literal hex in this file is a bug: it is the
 * one thing that cannot follow the theme, and a card glowing white in a dark
 * dashboard is the fastest way to look foreign.
 */

.block {
  font-family: var(--ds-font-family-body, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
  color: var(--ds-text);
  /*
   * Never wider than the widest width this card has ever been designed at.
   *
   * Jira's default dashboard layout is a single full-width column, and there
   * the card had no ceiling: measured at a 1100px column, the evidence line
   * ran to 1066px - 170-180 characters against the 45-75 a line should hold,
   * and past the 80 WCAG 1.4.8 puts a ceiling at. On a screen somebody reads
   * for ten seconds before a call, the eye loses the start of the next line.
   *
   * 560px rather than a number chosen for its own sake: the widest scene this
   * card has ever been reviewed at is 600px of column, which draws it at 566.
   * So nothing anybody has looked at moves, and every column wider than that
   * now draws the card the way it was designed rather than the way it stretches.
   */
  max-width: 560px;
  /* No background of its own: the dashboard already draws the card, and a
     second surface inside it reads as a box in a box. */
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-200, 16px);
  container-type: inline-size;
}

/*
 * Which board, and how fresh. The first line, deliberately small: it is what a
 * reader checks once and then stops seeing, and anything louder would compete
 * with the finding underneath it.
 */
.card-head {
  font-size: 11px;
  line-height: 1.4;
  color: var(--ds-text-subtle);
}

.card-board {
  font-weight: 600;
}

.item {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-050, 4px);
}

/*
 * The one thing set big is what a person would say out loud. Everything else
 * is context: a wall of equally-sized sentences gives the eye nowhere to land,
 * and a reader then judges the whole block by its worst line.
 *
 * 28px is a floor, not a preference — this gets read from three metres away on
 * a shared screen at standup.
 */
/*
 * The number, then what it is about, in that order and on that line - always.
 *
 * It used to wrap, and wrapping is what made a one-digit finding and a
 * two-digit one look like two different kinds of block: "8" fitted beside its
 * sentence and "11" did not, so the sentence dropped below and the numeral was
 * left standing alone. Same component, same payload shape, two layouts decided
 * by how wide the column happened to be dragged.
 *
 * So the row never breaks and the sentence wraps inside itself. `min-width: 0`
 * is what lets it: a flex item refuses to shrink below its longest word
 * otherwise, and the row would overflow instead of the text reflowing.
 */
.headline {
  display: flex;
  align-items: baseline;
  gap: var(--ds-space-100, 8px);
  flex-wrap: nowrap;
  /* It is an `h3` now, so that a screen reader can move between findings the
     way a sighted reader's eye already does. Everything a heading brings with
     it by default - its own size, its own weight, its margins - has to go: the
     size lives on `.count` and `.what`, and the spacing on `.item`. */
  font-size: inherit;
  font-weight: inherit;
  margin: 0;
}

/* The findings, as the list they are. The bullets and the indent are the
   browser's idea of a list and not this card's. */
.findings {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-200, 16px);
}

.headline .count {
  flex: none;
}

.headline .what {
  flex: 1 1 auto;
  min-width: 0;
}

.count {
  font-size: 28px;
  line-height: 1.1;
  font-weight: 600;
  color: var(--ds-text);
  font-variant-numeric: tabular-nums;
}

/* The unit beside the figure, at the size of the sentence it belongs to. */
.count-unit {
  font-size: 14px;
  font-weight: 400;
}

.what {
  font-size: 14px;
  line-height: 1.35;
  color: var(--ds-text);
}

.where {
  font-weight: 600;
}

/* The question. Never a verdict, and never louder than the fact above it. */
/*
 * How far past the usual, given its own line.
 *
 * The only number on a finding that compares with the next finding's: two
 * columns hold different amounts of work, so "8 of 10" and "11 of 13" cannot
 * be ranked against each other, and the multiple can. It was set in the same
 * grey as the sampling method, three clauses into a sentence - so the card was
 * ordered by something the reader had no way to see.
 */
.past-usual {
  font-size: 13px;
  font-weight: 600;
  color: var(--ds-text);
}

.ask {
  font-size: 13px;
  color: var(--ds-text-subtle);
}

.evidence {
  font-size: 12px;
  line-height: 1.5;
  color: var(--ds-text-subtlest);
}

/*
 * A single ticket gets a rail, not a chart. The band is where this column
 * usually sits; the mark is where this ticket stands. No axes, no legend —
 * anything that needs explaining is noise in a dashboard column.
 */
.rail {
  position: relative;
  height: 6px;
  /*
   * Capped for a different reason than the card above it, and a sharper one.
   *
   * The mark's position is quantised to five steps on purpose - `rail.js` says
   * why: steps turn an exact number into a range, so the threshold cannot be
   * recovered by algebra. That only reads as a range while the steps are close
   * enough together to look like stops. Measured at a 1100px column: a 3px
   * mark with 85px between the only positions it can occupy, which reads as an
   * exact measurement on a continuous scale.
   *
   * The drawing would then be promising a precision the number deliberately
   * does not have - the same class of error the headline bar was deleted for.
   * At 260px the stops are 18-21px apart, which is the width the rail was
   * designed and checked at.
   */
  max-width: 260px;
  border-radius: 3px;
  background: var(--ds-background-neutral);
  /*
   * The scale's own edge, and it was missing.
   *
   * The line and the mark were each measured and fixed against the band they
   * stand on - 3.78:1 and 4.46:1 - and the ground under both was never
   * measured at all: the track reads 1.13:1 against the card surface. So what
   * a reader could see was a hairline and a dash floating on nothing, with no
   * beginning and no end to the scale that gives them meaning. A reader of a
   * simulated run said outright they were guessing what the marks meant.
   *
   * A border rather than a louder fill, because the fill is the ground the
   * other two are measured against and moving it would move both of them.
   * `--ds-border-bold` is 3.90:1 in light and 4.22:1 in dark.
   */
  border: 1px solid var(--ds-border-bold, rgba(128, 128, 128, 0.6));
  box-sizing: border-box;
  margin: var(--ds-space-100, 8px) 0 var(--ds-space-050, 4px);
}

/*
 * Where the usual ends, drawn as an edge rather than left to a fill.
 *
 * The fill is what encodes the value and a reader measured it at 1.34:1
 * against the track in light and 1.39:1 in dark - under the 3:1 that a
 * graphical object needs - and described the dark card as an empty tube with a
 * dot in it. Making the fill loud enough to meet that would put a slab in a
 * six-pixel rail and drown the mark, which is the thing that moves.
 *
 * So the same answer the track was given for the same reason: an edge. The
 * value the band carries is where it *ends*, not how much of it there is, and
 * an edge is the part a reader was looking for.
 */
.rail-band {
  position: absolute;
  top: 0;
  bottom: 0;
  /*
   * The fill, raised to a colour a reader can actually see (OUT-385).
   *
   * `--ds-background-neutral-hovered` carries alpha - 0.14 in light, 0.12 in
   * dark - and the track under it is the same family at 0.06. Composited all
   * the way to the card, the band read 1.34:1 in light and 1.39:1 in dark
   * against the track it sits on, against the 3:1 WCAG 1.4.11 asks of a
   * graphical object. The band is the half of the rail the gap is measured
   * from, so the picture had lost its own comparison.
   *
   * `--ds-border-bold` measured on the live tokens, in the browser, with
   * compositing up the tree: 3.45:1 in light and 3.61:1 in dark against the
   * track. It is the softest opaque token in the set that passes on both
   * sides - the same rule the line was picked by, and the same token the
   * track's own border and this band's own edge already use, so the rail
   * gains a value and no new colour.
   *
   * Opaque on purpose. Every faint thing on this rail was faint for the same
   * reason: an alpha over an alpha over a surface nobody measured.
   *
   * Still quieter than the two things that move, which is what stops a
   * six-pixel rail competing with the figure beside it: band 3.45/3.61, line
   * 4.51/4.92, mark 5.32/8.98.
   */
  background: var(--ds-border-bold, rgba(128, 128, 128, 0.6));
  border-right: 1px solid var(--ds-border-bold, rgba(128, 128, 128, 0.6));
  border-radius: 3px;
}

/*
 * Where the line is, drawn and never labelled.
 *
 * The mark's position means how far past this line the ticket is - that is
 * what OUT-136 changed the scale to - and there was nothing on the rail at the
 * position it is measured from. So the only thing a reader could compare the
 * mark against was the end of the band, which is the usual, which is the
 * comparison OUT-136 measured as misleading.
 *
 * A hairline rather than a mark: it belongs to the rail, not to the ticket,
 * and it must not compete with the thing that moves.
 *
 * Quiet, but not invisible. Measured in the browser against the live tokens,
 * `--ds-border-bold` at 0.6 gave 1.97:1 against the rail and 1.80:1 against
 * the band - the one element on the card that says where the line is, under
 * the 3:1 WCAG 1.4.11 asks of a graphical object, and a good deal fainter than
 * the bar deleted for measuring 2.94:1. `--ds-text-subtlest` at full opacity
 * reads 4.51 and 3.78. It is the softest token that passes on both sides,
 * which is the reason it was picked over the darker ones that also do.
 */
.rail-line {
  position: absolute;
  top: -1px;
  bottom: -1px;
  width: 1px;
  background: var(--ds-text-subtlest);
  /*
   * And a hairline of the card's own ground either side of it.
   *
   * Raising the band's fill to an opaque token gave the line a second ground
   * it had never been measured against: where the column's usual reaches past
   * the point that raised the ticket, the band covers the line's position and
   * the line is drawn on top of it. Measured there, `--ds-text-subtlest` on
   * the raised band reads 1.31:1 in light and 1.36:1 in dark - so the line
   * would disappear on exactly the finding where its position matters most.
   * No opaque token in the set passes 3:1 against both the track and this
   * line; all twenty-eight were checked.
   *
   * So the line carries its own separation. On the band it reads 3.90:1 and
   * 4.22:1; on the track it reads 1.13:1 and is not visible at all, so the
   * ordinary rail is unchanged and only the covered case gains a notch. A
   * shadow rather than a border, because a border would move the line.
   *
   * One rail in fifty-three on the corpus is in that state.
   */
  box-shadow: 1px 0 0 var(--ds-surface), -1px 0 0 var(--ds-surface);
}

/*
 * One step bolder than the token this used, and measured rather than picked.
 *
 * The mark stands on two different grounds - the rail, and the band where the
 * column usually sits - and the band is the one that matters, because a mark
 * inside the usual is the ordinary case. Against the band, `-bolder` read
 * 2.96:1 in the light theme, under the 3:1 WCAG 1.4.11 asks of a graphical
 * object. That is the number the headline bar was deleted for, so it is a
 * threshold this card already holds itself to.
 *
 * Measured in the browser against the live tokens, both themes, with alpha
 * compositing all the way up the tree:
 *
 *              on the band     on the rail
 *   light          2.96 -> 3.96     3.98 -> 5.32
 *   dark           4.76 -> 5.97     6.62 -> 8.31
 *
 * Still orange, because the colour carries the meaning; only the step
 * changed. A ring in the surface colour would also have passed and was
 * rejected: on a 6px rail a 3px mark with a 1px ring either side is most of
 * the rail.
 */
.rail-mark {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 3px;
  border-radius: 2px;
  background: var(--ds-background-accent-orange-bolder-hovered, var(--ds-background-accent-orange-bolder));
}

/*
 * The quiet state is designed, not empty. A gadget that looks broken on a calm
 * day gets removed from the dashboard, and the calm day is what the product is
 * actually for.
 */
/* Scoped, because this stylesheet is inlined into a page that has a `.quiet`
 * of its own.
 *
 * The site uses the same word for a muted paragraph, and this rule won on
 * `display`: the front page's only call to action - the line saying where the
 * Marketplace link will appear and how to be told - became three flex rows,
 * the third of them starting with an orphaned comma. A gadget's stylesheet has
 * no business reaching outside the card it draws, and both of these are inside
 * one: `Block` renders it under the findings, `Shell` inside its own `.block`. */
.block .quiet {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-100, 8px);
}

.quiet-line {
  font-size: 14px;
  line-height: 1.4;
  color: var(--ds-text);
}

/*
 * Where the open work stands. The only drawing on a quiet morning, and it is
 * held to the same rule as the words: no traffic light. These are three places
 * work can be, not three grades — so they are three neutral hues of the same
 * weight, and none of them is red.
 */
.shape {
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-075, 6px);
}

.shape-bar {
  display: flex;
  width: 100%;
  height: 8px;
  border-radius: 4px;
  overflow: hidden;
  /* Visible even when a segment fails to paint: an empty rounded groove reads
     as "nothing here", where a missing bar reads as a broken card. */
  background: var(--ds-background-neutral, rgba(128, 128, 128, 0.15));
}

.shape-part {
  height: 100%;
}

/* A hairline between segments, so two adjacent hues do not merge into one
   shape at the sizes a gadget is actually read at. */
.shape-part + .shape-part {
  box-shadow: inset 1px 0 0 var(--ds-surface, #fff);
}

.shape-waiting {
  background: var(--ds-background-neutral-hovered, rgba(128, 128, 128, 0.3));
}

.shape-active {
  background: var(--ds-background-accent-blue-subtle, #579dff);
}

/*
 * Striped, not merely another colour - and the second stripe below is here
 * because the sentence this comment used to end with was measured and was
 * wrong.
 *
 * It said the other three segments were "already far apart in lightness". They
 * are not. Measured in the browser against the live tokens, composited over
 * the light surface, the relative luminance of the four is 0.725 / 0.333 /
 * 0.334 / 0.275 - so in greyscale, which is also how this bar looks on a
 * projector at standup:
 *
 *     in progress <-> review     1.00 : 1   identical
 *     in progress <-> elsewhere  1.18 : 1
 *     review      <-> elsewhere  1.18 : 1
 *     waiting     <-> in progress 2.02 : 1
 *
 * Three of the four are one flat grey. The stripe was carrying the whole of
 * the difference for one pair and nothing for the other two.
 *
 * So the two segments that are not separable by lightness each get a texture,
 * at opposite angles, and the two that are stay plain. Texture rather than
 * different colours because the colours are the design system's and mean
 * something; and because a stripe survives deuteranopia, protanopia,
 * greyscale print and forced-colours mode alike, none of which a hue does.
 */
.shape-review {
  background: var(--ds-background-accent-purple-subtle, #9f8fef);
  background-image: repeating-linear-gradient(
    135deg,
    rgba(255, 255, 255, 0.35) 0 2px,
    transparent 2px 5px
  );
}

/*
 * The opposite angle, and a wider gap, so the two textures are not a near-miss
 * of each other at the width a dashboard column gives this bar.
 */
.shape-elsewhere {
  background: var(--ds-background-accent-gray-subtle, rgba(128, 128, 128, 0.5));
  background-image: repeating-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.3) 0 2px,
    transparent 2px 7px
  );
}

.shape-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ds-space-050, 4px) var(--ds-space-150, 12px);
  font-size: 12px;
  color: var(--ds-text-subtlest);
}

.shape-key {
  display: inline-flex;
  align-items: center;
  gap: var(--ds-space-050, 4px);
}

/*
 * Words carry the meaning; this only ties a label to its segment. Shaped like
 * a fragment of the bar above rather than a square, because the streak below
 * is a row of squares meaning something else entirely — a morning each — and
 * stacked directly under the legend the two read as one thing. "first morning"
 * looked like a third segment of the bar.
 */
/*
 * The bar's colours, reused beside the counts in the footer that describe it.
 * Sized down and lifted onto the text's own line: the legend's dot sits beside
 * 12px type, and the footer is 11px.
 */

.shape-dot {
  width: 14px;
  height: 6px;
  border-radius: 3px;
  flex: none;
}

/* Five days of history, so the thing is visibly alive rather than stuck. */
.streak {
  display: flex;
  gap: var(--ds-space-050, 4px);
  align-items: center;
}

/*
 * One square per recent morning, filled where something was raised.
 *
 * Filled against outlined, not one hue against another - and that is a
 * correction. It was a subtle accent against `--ds-background-neutral`, and
 * measured in the browser against the live tokens the row carried its whole
 * meaning in a difference nobody can see: a filled square against the card
 * surface was 1.97:1 in light and 2.73:1 in dark, both under the 3:1 WCAG
 * 1.4.11 asks of a graphical object that carries information, and the
 * distinction that does the work - filled against empty - was 1.74:1 and
 * 2.34:1. An empty square against the surface measured 1.13:1, which is
 * nothing at all.
 *
 * A screen reader was told the whole thing through the row's label; the eye
 * was given a decoration. That is the same defect as the shape bar's, and it
 * is answered the same way: the state stops being carried by colour alone.
 * An outline and a fill differ in greyscale, on a projector, and to anybody
 * who separates no hues whatever.
 */
.streak-day {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  background: none;
  border: 1px solid var(--ds-border-bold, rgba(128, 128, 128, 0.6));
  /* Inside the ten pixels rather than outside them: the row sits under a
     sentence and a border-box square keeps the line height it was drawn for. */
  box-sizing: border-box;
}

.streak-day.spoke {
  /* The same mark the norm rail uses for "this one", so the card has one
     colour that means it rather than two that nearly do.

     One step of that ramp quieter than the rail's mark, and the difference is
     the ground rather than taste. The mark sits on the band, where `-bolder`
     measures 2.96:1 and fails - which is why the rail took the hovered step.
     These squares sit on the card itself, where the hovered step draws 6.02:1
     in light against 10.5:1 in dark, and that put a history of the gadget's
     own firing above every finding on the card for a reader in dark mode.
     Magenta rather than orange, and the reason is the ramp rather than the
     hue. Only these squares moved: the rail's mark sits on the band rather
     than on the card, its numbers are a separate measurement, and swapping a
     colour whose ground was not re-measured is how an unchecked number gets
     shipped. The design system's warm steps are asymmetric because their dark
     `-bolder` is a bright pastel: orange measures 4.51:1 in light against
     8.36:1 in dark, the widest gap of any accent step that clears 3:1 in both,
     so the same mark leads the card for a reader in dark and sits behind the
     sentence for a reader in light. Cool and red hues hold their luminance
     across themes; magenta draws 5.18:1 and 5.97:1, and it is the only
     chromatic one still unspent - blue, purple and grey are already the shape
     bar's, where grey means "elsewhere", and red reads as a verdict, which
     this product does not pass. Evening it by hand was the other way out and
     is refused: a literal here is the one thing that cannot follow a theme,
     the best value equal in both tops out at 3.92:1, and it would opt this
     mark out of the increased-contrast themes Atlassian ships today. */
  background: var(--ds-background-accent-magenta-bolder);
  border-color: var(--ds-background-accent-magenta-bolder);
}

/*
 * Not one of the carried lines.
 *
 * The payload carries this note as its own field precisely so the card can set
 * it apart, and the class was in the markup with no rule anywhere in the
 * repository - so it inherited the carried lines exactly, same size and same
 * faintest grey, one row under them. On the morning it fired it sat directly
 * beneath a coverage total that had dropped a quarter for an entirely
 * unrelated reason and read as the explanation of it.
 *
 * A rule above it and one step less faint: enough to say "this is about the
 * measurement, not about your board", and not enough to compete with a
 * finding.
 */
.method-changed {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--ds-border-bold, rgba(128, 128, 128, 0.6));
  color: var(--ds-text-subtle);
}

/* Same treatment as `.findings`: a list without the browser's bullets, which
   would sit beside a tick that is already doing that job. */
/*
 * The line that says whose ticks these are.
 *
 * Quieter than the ticks it stands over - it is a label, not a finding - and
 * the same size as the footer's prose, because that is the register of every
 * other sentence on the card that explains rather than reports.
 */
.cleared-head {
  font-size: 12px;
  color: var(--ds-text-subtle);
  margin-bottom: var(--ds-space-050, 4px);
}

.cleared-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ds-space-050, 4px);
}

.cleared {
  font-size: 12px;
  color: var(--ds-text-subtlest);
  display: flex;
  align-items: baseline;
  gap: var(--ds-space-050, 4px);
}

/* The one place a positive colour is allowed: something a person fixed. */
.cleared-mark {
  color: var(--ds-text-accent-green);
}

.still {
  font-size: 12px;
  color: var(--ds-text-subtlest);
}

/* The mornings before this card existed, in a register of their own.
 *
 * Not `.still`: that class is the carried findings, and every one of them
 * carries a link to the tickets it names. A reader learns the convention in a
 * week - grey line under the findings, click it, see the work - and this is
 * the one line on the card that cannot be opened, because it describes
 * mornings nobody watched. Wearing the same clothes it borrowed a trust it
 * cannot honour, on the product whose whole argument is that its sentences can
 * be checked.
 *
 * The rule on the left and the footer's own size, because that is what it is:
 * provenance, next to the sentence saying where the norms came from. Measured
 * before moving it: in the `.still` slot on a 200px column it was 112px of a
 * 619px card, taller than the answer it sat under. */
.hindsight {
  margin-top: 8px;
  padding-left: 8px;
  border-left: 2px solid var(--ds-border, #091e4224);
  font-size: 11px;
  line-height: 1.45;
  color: var(--ds-text-subtlest);
}

/* The footer and the button share one rule above them: the divider belongs to
   the row, not to the sentence, or the button hangs below a line it is part
   of. The button holds its own width and the footer takes the rest, because
   the footer wraps to three lines on a narrow gadget and the button must not
   shrink to an ellipsis. */
.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--ds-space-100, 8px);
  border-top: 1px solid var(--ds-border);
  padding-top: var(--ds-space-100, 8px);
}

/* Beside the footer while it is a button, and a full row of its own once the
   text has to be shown — a textarea squeezed into the right-hand column of a
   two-column row is unreadable at exactly the moment the reader has to read
   it.

   `flex-wrap` is what makes the second half true. `display: flex` arrived to
   hold "Copied" beside the button, and it put the fallback textarea in the
   same row as a third column: measured at a card width of 640, the textarea
   came out 293px wide, starting 143px in. `.copy.open` had widened the
   container and nothing else — the squeeze this comment forbids had simply
   moved one level down. */
.copy {
  /*
   * `min-width: 0` and `flex-wrap` are what is left of an older argument.
   *
   * The row was once `flex: none`, which meant the wrap below could never
   * fire - an item that cannot shrink keeps the width of both buttons side by
   * side, so there is no line to wrap onto, and at 200px the pair measured
   * 220px inside a 166px card. It was fixed with `flex: 0 1 auto`, and then
   * the whole row was given a line of its own for the reason below, which
   * settles the same thing more directly. Both survive because at 220px the
   * two buttons still have to stack inside that line.
   */
  /*
   * One home, on its own line.
   *
   * It was a flex item beside the footer's sentence, pushed to the far edge by
   * `space-between` - and that sentence is two lines when the counting note is
   * folded open and one when it is not, so the row wrapped or did not
   * depending on a disclosure that has nothing to do with these buttons. A
   * reader opened the note and watched both controls jump from the right edge
   * to the left. A control that moves when you look at something else is a
   * control you have to find again every time.
   *
   * A line of its own is the same place in both states and at every width -
   * which is also where it landed on a narrow card anyway.
   */
  flex: 1 0 100%;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  /*
   * The two buttons stood shoulder to shoulder with nothing between them.
   * Invisible while they were transparent with a hairline border - the border
   * was the gap - and a single filled slab the moment they were given a
   * background.
   */
  gap: var(--ds-space-075, 6px);
}

.copy-manual {
  flex-basis: 100%;
}

/* The trial's last days: a sentence the reader cannot act on themselves, so
   it is quieter than the findings and louder than the footer. No colour, no
   icon, no border — an alarm about billing on a card about a board would be
   the product doing to its reader exactly what it promises not to do to a
   team. */
.trial-ending {
  font-size: 12px;
  line-height: 1.5;
  color: var(--ds-text-subtle);
  margin-top: 12px;
}

.footer {
  font-size: 11px;
  line-height: 1.5;
  color: var(--ds-text-subtlest);
}

/* Quiet on purpose. This is the second thing on the card worth doing, after
   reading it, and a filled button competes with the one accent the block is
   allowed. */
/*
 * The two things anybody presses on this card, and they read as a browser's
 * own default: 11px, hairline border, transparent. Given the weight of a
 * control without being given emphasis - neither of them is the default
 * action, which is a decision about somebody's thread rather than about this
 * product.
 */
/*
 * The one action, at the size a button is meant to be.
 *
 * It was 24px tall - exactly the floor WCAG 2.5.8 allows for a target, with
 * nothing under it, and below the 32px Atlassian gives a button. Fitts's law
 * is not about compactness: a small target aimed at once a day is a target
 * missed once a day. 32px costs 8px on a card and buys the difference.
 */
.copy-button {
  flex: none;
  font: inherit;
  font-size: 12px;
  min-height: 32px;
  color: var(--ds-text);
  background: var(--ds-background-neutral, rgba(128, 128, 128, 0.15));
  /*
   * A boundary, rather than a fill hoping to be one.
   *
   * The border was transparent, so the only thing separating this control from
   * the card was its own ground - 1.13:1 in light and 1.17:1 in dark against
   * the surface, where 3:1 is what a control's boundary is asked for. Two
   * people found it separately, one on a real dashboard, and both described it
   * as not looking like a button. `--ds-border-bold` measures 3.90:1 and
   * 4.22:1, which is the same edge the rail's track was given for the same
   * reason.
   */
  border: 1px solid var(--ds-border-bold, rgba(128, 128, 128, 0.6));
  border-radius: 3px;
  padding: 4px var(--ds-space-125, 10px);
  cursor: pointer;
}

/*
 * The variation on it, as a link.
 *
 * Two equal buttons made a reader choose with no criterion; a link beside a
 * button says "this, or this with more in it" without asking.
 *
 * Quiet rather than link-coloured, and that is a correction. It used to wear
 * the ticket keys' blue on the grounds that both are "something you can act on
 * that is not the main thing" - but the keys are the findings, and this is a
 * second way to copy them. Two blues on one card compete, and the louder one
 * was the one that mattered least: on a card with three keys and this button,
 * four things asked for the eye and only three of them were the board.
 *
 * The underline is gone with the shape - what reads as a control at rest is
 * now the outline, for the reasons directly below. Hover still lifts the
 * label to full-strength text, and deliberately not back to the link colour:
 * bringing the blue back on hover restores the thing this rule exists to
 * avoid, one moment later, and by then the reader's cursor is already on it -
 * the one place feedback is least needed to shout. Blue on this card belongs
 * to the ticket keys.
 *
 * Keyboard focus is covered by the ring every control on the block shares, so
 * it needs nothing here.
 */
/*
 * The second control, shaped like the first.
 *
 * It was underlined text with no horizontal padding and a thirty-two pixel
 * height - a box that hugged its words on the sides and stood well clear of
 * them above and below, so the focus ring came out lopsided and touched the
 * button next to it. Underlined but not the link colour, it also matched
 * neither the ticket keys nor the column links, leaving the card with three
 * link-ish treatments and this one belonging to none of them. A reader put it
 * as "neither shaped like the other".
 *
 * So: the same shape, outlined rather than filled. That is what a second
 * choice beside a first one looks like, it gives the ring a control to wrap,
 * and the underline is not needed once the thing is visibly a button.
 */
.copy-more {
  flex: none;
  font: inherit;
  font-size: 12px;
  min-height: 32px;
  padding: 4px var(--ds-space-125, 10px);
  color: var(--ds-text-subtle, #626f86);
  background: none;
  border: 1px solid var(--ds-border-bold, rgba(128, 128, 128, 0.6));
  border-radius: 3px;
  cursor: pointer;
}

.copy-more:hover {
  color: var(--ds-text);
}

/*
 * Spent, on a morning with nothing extra to attach.
 *
 * `aria-disabled` rather than `disabled`, so this is a look rather than a
 * removal: the button keeps its place in the tab order and answers when
 * pressed. The cursor says the press will not do the usual thing, and the
 * hover rule is cancelled so nothing about it promises otherwise. The colour
 * is left alone deliberately - dimming it further would put the one control
 * that has something to say below the contrast the rest of the card holds.
 */
.copy-more[aria-disabled='true'] {
  border-style: dashed;
  cursor: default;
}

.copy-more[aria-disabled='true']:hover {
  color: var(--ds-text-subtle, #626f86);
}

/*
 * The third button, spent for the other reason (OUT-341).
 *
 * Rovo is there and the morning has nothing to hand it. The same look as the
 * button beside it, because it is the same state - a control that keeps its
 * place and answers when pressed - and a second way of drawing one state is a
 * reader learning two things where there is one.
 */
.button-second[aria-disabled='true'] {
  border-style: dashed;
  cursor: default;
}

.button-second[aria-disabled='true']:hover {
  color: var(--ds-text-subtle, #626f86);
}

/*
 * The middle weight, and the reason there has to be one.
 *
 * The card had two: a filled slab and quiet underlined text. Everything that
 * was neither had to pick one of them, and both picks were wrong somewhere.
 *
 * `Ask Rovo why` took the quiet text, and it is the newest control on the card
 * and the least self-explanatory - the one thing that hands the morning to
 * somebody else looked like the least of the three things in its row. A
 * hundred pixels above it sit blue underlined ticket keys, so the card was
 * teaching two rules at once: blue underlined navigates, grey underlined acts.
 * Contrast was never the problem (7.81 light, 7.15 dark); shape was. At 210px
 * it dropped to its own line with an indent and read as a footer link.
 *
 * `Copy diagnostic` took the filled slab, which put it at the weight of the
 * card's own `Copy` on the one card that carries both. They are for entirely
 * different things - one is a paste for a thread, the other is for a bug
 * report - and at a glance they were the same button twice.
 *
 * So: filled is the thing to do here (`Copy`, `Try again`), outlined is a
 * second thing that is also a control. There were three weights and there are
 * now two - `.copy-more` was the underlined one, and it took the outline when
 * its focus ring turned out to need a box to sit in. What separates it from
 * this rule today is the text token alone (`--ds-text-subtle` against
 * `--ds-text`), which is thinner than the argument above assumes; if a third
 * weight is wanted again, it has to be built rather than remembered. No fill,
 * so it does not compete with the one accent the block is allowed, and the
 * same 32px target `.copy-button` is held to.
 *
 * `--ds-border-bold` rather than `--ds-border`, and that is the whole of
 * whether this works. Measured in the browser against the live tokens, over
 * the card's own surface: `--ds-border` draws at 1.35:1 in light, a line
 * nobody sees - which would have left the control looking like text again
 * with a rule in the stylesheet claiming otherwise. The bold token measures
 * 3.90:1 in light and 4.22:1 in dark, over the 3:1 WCAG 1.4.11 asks of the
 * boundary that identifies a control. Here the boundary is all there is: no
 * fill, and the label is not underlined any more.
 */
.button-second {
  flex: none;
  font: inherit;
  font-size: 12px;
  min-height: 32px;
  color: var(--ds-text);
  background: none;
  border: 1px solid var(--ds-border-bold, rgba(128, 128, 128, 0.6));
  border-radius: 3px;
  padding: 4px var(--ds-space-125, 10px);
  cursor: pointer;
}

.button-second:hover {
  background: var(--ds-background-neutral, rgba(128, 128, 128, 0.15));
}

/*
 * The one control on a broken card that fixes it, and it was the smallest
 * thing on the screen.
 *
 * Measured on the failed state at 300px: `Try again` 70x22, with `Copy
 * diagnostic` beside it at 113x32. WCAG 2.5.8 asks for 24x24 and neither
 * exception applies - this is a flex child on its own row, not text inline in
 * a sentence. It had no rule at all, so it was taking the browser's default
 * button metrics.
 *
 * Worse than the measurement: the button that recovers was half the size of
 * the one that copies a diagnostic for a bug report. The reader on this screen
 * wants the first one.
 */
.retry {
  font: inherit;
  font-size: 12px;
  min-height: 24px;
  padding: 4px 10px;
  color: var(--ds-text);
  background: var(--ds-background-neutral, rgba(128, 128, 128, 0.15));
  border: 1px solid transparent;
  border-radius: 3px;
  cursor: pointer;
}

.retry:hover {
  background: var(--ds-background-neutral-hovered, rgba(128, 128, 128, 0.3));
}

.retry[disabled] {
  cursor: default;
  opacity: 0.6;
}

.copy-button:hover {
  background: var(--ds-background-neutral-hovered, rgba(128, 128, 128, 0.3));
}

/* Outside the button, not inside it: the label is the button's accessible
   name, and a name that changes to "Copied" leaves a screen reader announcing
   a past event where a person expects an action.

   Everything this comment used to say about reserving *width* is gone with
   the reservation - the row is no longer pushed right by a `space-between`
   parent and no longer sized to the longest word it can hold. What that cost
   and why it went is directly below. */
/*
 * Under the buttons, not beside them.
 *
 * It sat in the row with a reserved width, and the reservation was too small
 * for the longest thing it says: pressing "with evidence" put "Copied with
 * evidence" into six rems of space, which grew the row, pushed it past the
 * card's edge on a narrow dashboard column and moved both buttons sideways at
 * the moment of the press. Reserving width for a sentence is a bet on its
 * length, and it was lost in the one language this ships in.
 *
 * A line of its own takes the bet off the table: the row's width no longer
 * depends on what the status says, in any language. The height is reserved
 * whether or not anything is in it, so pressing moves nothing at all.
 */
.copy-said {
  flex-basis: 100%;
  min-height: 16px;
  font-size: 11px;
  line-height: 16px;
  color: var(--ds-text-subtlest);
}

/*
 * A copy that did not happen, told apart from one that did.
 *
 * Both used to be the same eleven-pixel grey line, so a reader who glanced
 * away could not tell "Copied" from "Not copied" - and the failure said only
 * that, with nothing about what to do instead, which is the whole of WCAG
 * 3.3.3 where the way out is known. The way out is to select the card and copy
 * by hand, so the message says so, and the sentence carries the state as well
 * as the colour: in forced colours the colour is gone and the words are not.
 */
.copy-said.failed {
  color: var(--ds-text-danger, #ae2e24);
}

.copy-manual {
  margin-top: var(--ds-space-100, 8px);
}

.copy-text {
  width: 100%;
  /* Everything else on the card is border-box; a textarea is not by default,
     so `width: 100%` plus its padding, border and scrollbar came to 176px
     inside a 166px card - the one element that hung over the edge, and only
     on the path where the clipboard had already refused. */
  box-sizing: border-box;
  margin-top: var(--ds-space-050, 4px);
  font-family: var(--ds-font-family-code, monospace);
  font-size: 11px;
  color: var(--ds-text);
  background: var(--ds-surface-sunken, transparent);
  border: 1px solid var(--ds-border);
  border-radius: 3px;
  padding: var(--ds-space-050, 4px);
  resize: vertical;
}

/*
 * Room to hit them.
 *
 * Measured: each key was 78x14px with 18px between the rows, which fails
 * WCAG 2.2 SC 2.5.8 both ways - under the 24px minimum and under the 24px
 * spacing exception that would otherwise excuse it. These are the only things
 * on the card anybody presses, and on a touch screen or a trackpad they were
 * a coin toss between two tickets.
 *
 * Padding rather than height, so the line of keys still reads as a line of
 * text rather than as a row of buttons.
 */
.keys {
  display: flex;
  flex-wrap: wrap;
  /*
   * Wide enough for two rings between two keys.
   *
   * The ring stands three pixels outside its element, so two of them need six
   * pixels of gap before they touch and more than that before there is any
   * daylight. At eight there were two pixels between one reader's ring and the
   * next key's word, which is what "the frame is crooked" turned out to mean.
   * The first attempt kept the words where they were by pulling the padding
   * back with a negative margin, which made the boxes meet and the rings
   * overlap outright - worse than what it fixed.
   */
  gap: var(--ds-space-050, 4px) var(--ds-space-150, 12px);
  font-size: 12px;
  /*
   * And no negative margin to line the first word up with the prose above it.
   *
   * That was tried, and it cost the focus ring its left side: the padding puts
   * the first key's box four pixels left of the card's text edge, the ring
   * stands three further out, and seven pixels out is past what the card has
   * to give - so the ring came back as three sides and a gap where the fourth
   * should be. A word sitting four pixels in from the paragraph above it is a
   * small thing. A focus ring missing a side is not.
   */
}

/*
 * Room on all four sides, so the ring is a shape rather than a smear.
 *
 * The padding was vertical only, which put the focus ring eight pixels from
 * the word above and below it and three at the sides - and between two keys,
 * with eight pixels of gap, that left two pixels of daylight between one
 * reader's ring and the next key's text. A ring that is far away in one
 * direction and touching in the other does not read as a box round the thing
 * you are on; it reads as a mistake.
 *
 * The words did move, and an earlier version of this comment said they did
 * not. Measured edge of text to edge of text: 8px before, 20px after - the
 * 12px gap plus 4px of padding on each side. The padding is what the inset
 * ring sits in and is not negotiable; the gap on top of it is a leftover from
 * when the ring was drawn outside and two of them could touch. Both are
 * pinned by a test now, so the next person to change either has to mean it.
 */
.keys .key,
.keys .evidence {
  padding: 5px 4px;
}

/*
 * Underlined, always, and not only on hover.
 *
 * Colour alone is the whole of what marked these as links, which is the one
 * thing a reader who does not see colour cannot use (WCAG 1.4.1) - and three
 * keys separated by a single space read as one long link even for a reader who
 * does. The underline separates them as well as marking them.
 */
.key {
  color: var(--ds-link);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.key:hover {
  text-decoration: underline;
}

/*
 * The column is a width the user drags. Below roughly 260px the headline has to
 * stop competing with itself for the line.
 */
@container (max-width: 260px) {
  .count {
    font-size: 22px;
  }
  .headline {
    gap: var(--ds-space-050, 4px);
    /*
     * And where even that is not enough, the sentence takes its own line.
     *
     * `nowrap` is right for a headline whose count is a numeral: "6" leaves
     * 148 of 166px for the words beside it. It is wrong for one whose count is
     * a phrase - "3 working days" is the whole line at 200px, and the words
     * after it were being squeezed into a 10px column three lines tall, one
     * word per line.
     */
    flex-wrap: wrap;
  }

  /*
   * What decides which of the two happens.
   *
   * Wrapping alone moved both headlines: with `flex-basis: auto` the sentence
   * asks for its whole natural width, so even "6" got pushed onto a line of
   * its own - the exact thing the nowrap rule exists to prevent. `min-width`
   * does not fix it either, because what decides the wrap is the basis, not
   * the floor. So the basis becomes the floor: the sentence asks for six
   * characters, keeps its place beside the count while those fit, and takes
   * its own line once they do not. Measured at 200px, the numeral headline
   * stays on one line and the phrase headline becomes two.
   */
  .headline .what {
    flex: 1 1 6ch;
  }
}

/*
 * Keyboard focus, on the one interactive thing the card has.
 *
 * The form styles focus on every control; the card had nothing but the
 * browser default, and a default inside an iframe carrying somebody else's
 * reset is a default that can quietly not exist.
 */
/* The textarea joined the list rather than being left to the UA default,
   which measured 1.74:1 against the card - the same default this comment
   already distrusts, on the one control that appears exactly when something
   has gone wrong. */
/* And `summary`, which is a focus stop the moment a `<details>` exists. That
   makes three elements added to this card that arrived without a ring - the
   textarea, the form's Change link, and now this - so the rule is written to
   cover the kinds rather than the instances. */
.block a:focus-visible,
.block button:focus-visible,
.block textarea:focus-visible,
.block summary:focus-visible {
  outline: 2px solid var(--ds-border-focused, Highlight);
  /*
   * Drawn inside the control, not around it.
   *
   * Outside, it left the card. The first ticket key and the Copy button both
   * sit flush with the card's left edge, so a ring standing two pixels clear of
   * them is two pixels outside the card - and the gadget's own frame cuts it
   * there. What a reader saw was a box with three sides and a gap where the
   * fourth should be, and no amount of moving the row around fixed it, because
   * the room was never on that side to begin with.
   *
   * Inset, it cannot leave: every control it lands on has padding of its own -
   * that is what the padding is for - so the ring sits in it, clear of the
   * word and clear of the edge, at any width and wherever on the card the
   * control happens to be.
   */
  outline-offset: -2px;
  border-radius: 3px;
}

/*
 * The one control that had no padding to hold the ring.
 *
 * The rule above says every control it lands on has padding of its own. That
 * was true of every control it was checked against and false of this one: a
 * ticket key inside a "still open" line is a `.key`, but it is not inside
 * `.keys`, so the padding that sentence relies on never applied to it, and
 * the inset ring came out two pixels *inside* the glyphs on all four sides.
 *
 * Fixed once by sending the ring back outside, on the grounds that this
 * element sits 26px from the card's edge and has room. That was true of one
 * of the two sentences `StillLine` draws. The other makes the link a *column
 * name* in the middle of the line, and a name from a real board wraps: the
 * second fragment begins at the card's own text edge, and the ring was
 * measured 4px past it - three sides and a gap where the fourth should be,
 * which is the defect the inset ring exists to prevent. From 30 characters at
 * 220px, and from 44 at 300, which is the width the preview opens at.
 *
 * So: padding, like every other control, and `box-decoration-break: clone` so
 * that each fragment of a wrapped line gets its own rather than the first
 * getting the left and the last the right. Measured on a wrapped link at
 * 220px: 0px past the card, 0 fragments with the ring on the glyphs. The four
 * arrangements tried before it each failed one of those two.
 */
.still .key {
  padding: 2px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}

/*
 * Windows High Contrast strips background colours, which takes both bars with
 * it - the shape bar and the flagged bar are backgrounds and nothing else. The
 * numbers are all in the text beside them, so nothing is lost to a reader; what
 * is lost is the bar quietly becoming an empty gap. Drawn as an outline
 * instead, in the one colour that mode guarantees.
 */
@media (forced-colors: active) {
  .bar,
  .shape-bar {
    border: 1px solid CanvasText;
  }

  .bar-flagged,
  .shape-part {
    forced-color-adjust: none;
    background: CanvasText;
  }

  .shape-part + .shape-part {
    box-shadow: inset 1px 0 0 Canvas;
  }

  /*
   * Filled and empty, still told apart when the accent is taken away.
   *
   * The comment on the fill says the distinction survives without colour, and
   * in greyscale it does - but under forced colours the accent is replaced by
   * the system's own palette and a filled square became an empty one. The row
   * kept rendering and stopped meaning anything.
   */
  .streak-day.spoke {
    forced-color-adjust: none;
    background: CanvasText;
    border-color: CanvasText;
  }

  .streak-day {
    forced-color-adjust: none;
    background: Canvas;
    border-color: CanvasText;
  }
}

/*
 * No minimum height.
 *
 * There was one - 420px - added to stop the card changing height between a
 * quiet morning and a loud one, on the strength of measurements taken in the
 * preview, where the frame is exactly as tall as the card. On a real
 * dashboard it is not: the gadget's height belongs to the dashboard, the card
 * sits inside whatever it is given, and the neighbours below never moved in
 * the first place.
 *
 * So it stabilised nothing and cost white space: measured on the live board,
 * 169px of it at 600px wide, 88px at 300px. The one place the reader could
 * see it was the one place it was not needed.
 */

/*
 * The columns, where the stacked bar used to be.
 *
 * One line, wrapping on a narrow column rather than truncating: the numbers
 * are the point, and an ellipsis would hide exactly the one that moved.
 *
 * Movement was marked by weight of colour alone, and a column that had not
 * moved stepped back to `--ds-text-subtlest`. Measured against the card:
 * 14.34:1 for a column that moved and 5.10:1 for one that did not, in light;
 * 10.56 and 5.76 in dark. Neither is a contrast failure - both clear the 4.5:1
 * asked of body text - and it still went wrong twice over.
 *
 * A reader looking at the pictures read the grey column as text that had
 * failed to load, and waited for it to finish. Nearly three times the contrast
 * of its neighbours is a big step for something that is only "less
 * interesting", and there is nothing in the line to say which of the two
 * meanings a faded word carries.
 *
 * And on the morning every moved column was named in a line below, the "was"
 * was suppressed on all of them and colour became the *only* carrier of the
 * fact that anything had moved at all - which is 1.4.1, and unreadable in
 * greyscale or on a projector.
 *
 * So: the unmoved steps back by one token rather than two, and the moved
 * carries weight as well as colour. Two channels, each of them smaller than
 * the single one they replace.
 */
.columns {
  font-size: 12px;
  line-height: 1.6;
  color: var(--ds-text-subtle);
}

/*
 * The line breaks between columns, never inside one.
 *
 * At a dashboard column's width this wraps - measured, ten mornings of ten at
 * 300px and nine of ten at 340px - and it used to break wherever the text ran
 * out, which severed a count from the name it belongs to seven times in
 * nineteen: "\u00b7 6" on one row and "Code Review, was 5" on the next. A
 * number without its column is the one thing this line exists not to say.
 *
 * Holding each column together is not enough on its own: the separator is
 * drawn inside the column that follows it and there is no whitespace between
 * the spans, so an unbreakable column leaves the line with nowhere to break
 * at all and the card overflows its own width - measured at 220 and 300px.
 * Wrapping as a row of items puts the break opportunities between columns,
 * which is where they were always meant to be.
 */
.columns {
  display: flex;
  flex-wrap: wrap;
  /*
   * The space before the separator, given back.
   *
   * Each column is a flex item now, and a leading space at the start of an
   * item is trimmed the way a leading space at the start of a line is - so
   * "9 In Progress · 3 Code Review" rendered as "9 In Progress· 3 Code
   * Review", with the bullet welded to the word before it. A reader of a
   * simulated run reported it on every card. The separator's own spaces used
   * to do this job in ordinary inline flow; between flex items it is the
   * container's to do.
   */
  column-gap: 0.3em;
}

.column {
  white-space: nowrap;
  max-width: 100%;
}

.column.moved {
  color: var(--ds-text);
  /* The channel that is not a colour. On most mornings every column moves and
     the line is uniform, which is correct - there is nothing to pick out. It
     earns its place on the mornings some moved and some did not, and those are
     the mornings a reader is trying to read. */
  font-weight: 600;
}

.columns .shape-dot {
  display: inline-block;
  width: 10px;
  height: 5px;
  margin-right: 4px;
  vertical-align: middle;
}

/*
 * Heard, not seen.
 *
 * One line, announced when the wait for a board's history ends. Not
 * `display: none` and not `visibility: hidden` - both take the element out of
 * the accessibility tree, which is the one place it needs to be.
 */
.offscreen {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/*
 * The half of the denominator that folds.
 *
 * Its own line rather than a run-on: `<details>` is a block, and inline-ing it
 * put "how this was counted" mid-sentence between two clauses it is not part
 * of. The marker is the browser's own - it is the one affordance a reader
 * already knows, and drawing our own would be a triangle nobody has seen.
 */
.footer-more {
  display: block;
  margin-top: var(--ds-space-050, 4px);
}

.footer-more > summary {
  cursor: pointer;
  /*
   * A target, not a line of text. Measured at 123x17 on every card, with the
   * nearest other target - the copy button - 8px away on a 266px column. WCAG
   * 2.2 asks 24px, and neither exception rescues it: this is its own row
   * rather than a link inside a sentence, and 8px is not the 24px the spacing
   * exception wants. It depends on a width the reader drags, which is the
   * worst kind of failure to reason about.
   *
   * Padding grows the target; the negative margin gives the layout its space
   * back. Measured after: 123x25, and the card's own height unchanged.
   */
  padding: 4px;
  margin: -4px 0;
  /* A summary is a focus stop, and the card's own ring belongs on it as much
     as on a button. */
  border-radius: 2px;
  /* `list-item` keeps the disclosure triangle; Safari drops it otherwise. */
  display: list-item;
  width: fit-content;
}

.footer-folded {
  margin-top: var(--ds-space-050, 4px);
}


/*
 * The automation action's configuration form.
 *
 * Its own small sheet rather than the card's: this renders inside the rule
 * editor, which is a different host with a different surface, and the block's
 * stylesheet is written for a dashboard card that deliberately draws no
 * surface at all.
 *
 * Atlassian's own tokens, the same ones the card uses, so the form takes the
 * editor's theme rather than carrying one. Every value falls back, because a
 * token that is not defined in this host would otherwise render as nothing -
 * which is how the card once lost its accent colours.
 */

/* A surface of its own, unlike the card.
 *
 * `index.css` makes the body transparent, and it is right to: the block is
 * drawn inside a dashboard card that already has a surface, and anything
 * opaque there is a second box. This is not that. It is a panel in the rule
 * editor with nothing behind it but the browser's white canvas, so with the
 * host's dark theme enabled the text would be light on white. */
body {
  background: var(--ds-surface, #fff);
}

.actionform {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0.75rem;
  font-family: var(--ds-font-family-body, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif);
  font-size: 14px;
  color: var(--ds-text, #172b4d);
}

.actionform label {
  font-weight: 600;
  font-size: 12px;
  margin-bottom: 0.25rem;
  color: var(--ds-text-subtle, #44546f);
}

/* The sentence under each field, which is where the two things a person has to
   know actually live: where a board id comes from, and when the second field
   matters at all. */
.actionhint {
  margin: 0.35rem 0 1rem;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ds-text-subtlest, #626f86);
}

/* The list itself, which is the only control here. There is no button: the
   panel this renders into has Back and Next of its own, and the choice is
   handed back the moment it is made. */
.actionform select {
  font: inherit;
  padding: 0.35rem 0.5rem;
  border-radius: 3px;
  border: 1px solid var(--ds-border-input, #8590a2);
  background: var(--ds-surface, #fff);
  color: inherit;
}

.actionform select:focus-visible {
  outline: 2px solid var(--ds-border-focused, #388bff);
  outline-offset: 0;
  border-color: transparent;
}

.actionform select:disabled {
  color: var(--ds-text-disabled, #091e424f);
}

/* Why the list is empty, said where a sentence has room to wrap.
 *
 * It used to be the text of the disabled first row of the select, where the
 * longest of the three - the one that says how to fix the emptiness - needed
 * 510px of a 396px control and was cut off mid-word. Subtle rather than red:
 * an empty list on a first visit is a state, not a fault. */
.actionstate {
  margin: 0.35rem 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ds-text-subtlest, #626f86);
}

/* Two things a person in this panel cannot otherwise see: a field the editor
   has already judged incomplete, and a failure handing the choice back. Both
   read the same because both mean the same to the reader - this step will not
   work until something changes here. */
.actiontrouble {
  margin: 0.35rem 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: var(--ds-text-danger, #ae2e24);
}

/* And the control itself says so, not only the sentence under it: a message a
   reader has to connect to a field by proximity is a message they can attach
   to the wrong one. */
.actionform select[aria-invalid='true'] {
  border-color: var(--ds-border-danger, #c9372c);
}

/* The rule above wins back its own border on focus.
 *
 * `:focus-visible` sets `border-color: transparent` so the outline is the only
 * ring - which on an invalid field erased the red exactly when somebody
 * returned to fix it, breaking the link between the message and the field it
 * is about at the moment that link is needed. */
.actionform select[aria-invalid='true']:focus-visible {
  border-color: var(--ds-border-danger, #c9372c);
  outline-offset: 2px;
}
