/* /Components/Controls/CalendarView.razor.rz.scp.css */
/* One rule for twenty-four colours.

   The accent classes publish `--tp-mark` beside their background (D-057), so a single declaration
   can read whichever mark the entry carries. Writing `.k-event.tp-accent-red { … }` twenty-four
   times would be twenty-four things to keep in step with the palette, and the palette has already
   been re-tuned once.

   `::deep` is required and is the whole lesson of the tree stylesheet: the scope attribute lands only
   on elements written in *this* component's markup, and the event boxes are drawn by the scheduler.
   Anchoring on `.tp-calendar`, which is ours, is what lets the rule reach them. */
.tp-calendar[b-em6k09zyxm]  .k-event.tp-entry {
    background-color: var(--tp-mark, var(--tp-blue));
    border-color: transparent;
    color: #fff;
}

/* An entry with no mark. This class is what the earlier comment here claimed was already happening
   and was not: the class above was only put on entries that *had* an accent, so everything unmarked
   fell through to the vendor's own event colour -- a strong red-orange, which in a calendar reads as
   "urgent" or "conflict" and was neither. An unmarked appointment is the ordinary case and has to
   look like it.

   Grey rather than the interface blue, which was the other candidate. Blue is the colour of things
   you can click (D-059), and a whole week of blue boxes would spend the one signal the calendar has
   on the entries that are saying the least. Quiet grey leaves the colour to the people who chose one.

   Written after the rule above, and that matters: both selectors carry the same weight, so this one
   wins on order alone. It has to reset the colour as well as the background -- white text on light
   grey is the bug this change exists to avoid making. */
.tp-calendar[b-em6k09zyxm]  .k-event.tp-entry-plain {
    background-color: #e9ecef;
    border-color: #ced4da;
    color: #212529;
}

/* A band: the days themselves saying something, not an appointment on them.

   Deliberately unlike both of the rules above. An accented entry is a thing somebody marked and a
   plain one is a thing nobody marked; this is neither -- a closure belongs to nobody, and painting it
   out of the palette would make it look like a course with a colour. Hatched rather than solid,
   because a solid bar the width of a week reads as a very long appointment, which is the one thing it
   must not be mistaken for.

   `pointer-events: none` is the whole of why it cannot be dragged, opened or resized. The handlers in
   the component check as well and neither guard is spare: this stops a gesture from starting, and they
   stop one that started some other way. */
.tp-calendar[b-em6k09zyxm]  .k-event.tp-band {
    background-color: #f1f3f5;
    background-image: repeating-linear-gradient(
        45deg,
        transparent,
        transparent .4rem,
        rgba(0, 0, 0, .05) .4rem,
        rgba(0, 0, 0, .05) .8rem);
    border-color: #dee2e6;
    color: #495057;
    font-style: italic;
    pointer-events: none;
}

.tp-calendar[b-em6k09zyxm]  .k-event {
    border-radius: .25rem;
}

/* What is inside a timed box in the day and week views, where the time has been taken out and a name
   put in its place.

   A column and not a line, because the two say different kinds of thing: the title is what the
   appointment is, the name is who it belongs to, and running them together with a dash makes a reader
   parse where one ends. `min-width: 0` is what lets the ellipsis below work at all -- a flex child
   defaults to its content's width and will not shrink far enough to be cut.

   `overflow: hidden` on the box rather than a fixed height: how tall a box is belongs to how long the
   appointment is, and a half-hour lesson has room for one line. The title wins that room; see below. */
.tp-calendar[b-em6k09zyxm]  .k-event .tp-event {
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
    padding: .05rem .15rem;
}

/* The title never wraps and never disappears. A wrapped title in a box two lines tall pushes the name
   out of sight, which turns a second line into a coin toss between the two things the box says. */
.tp-calendar[b-em6k09zyxm]  .k-event .tp-event-title {
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Quieter than the title and in the same colour, not a paler one: the boxes come in twenty-four
   accents plus a light grey, so a hard-coded second colour would be wrong on most of them. Opacity
   fades whatever the box already decided the text should be, which is right on all twenty-five. */
.tp-calendar[b-em6k09zyxm]  .k-event .tp-event-lead {
    font-size: .75rem;
    line-height: 1.2;
    opacity: .8;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The vendor's own "show full day / show work day" toggle, which sits in the scheduler's footer.
   Hidden rather than configured away: it is not a toolbar tool and the component exposes no parameter
   for it -- `ShowWorkHours` is internal -- so there is no supported way to leave it out.

   It has to go, because Taskplan now has its own switch for exactly these two ranges, drawn under the
   calendar. Two controls for one question is worse than the wrong label we started with: they would
   disagree the moment somebody used the vendor's, which changes what is drawn without our switch
   knowing, so the highlighted button would then be lying.

   `::deep` because the scheduler's markup belongs to Telerik and carries none of this component's
   scope attribute (D-028: the vendor is named in one file, and this is that file). */
.tp-calendar[b-em6k09zyxm]  .k-scheduler-footer {
    display: none;
}

/* The vendor's own idea of a non-working day, switched off.

   It shades what *it* thinks the weekend is, worked out from the reader's culture -- so a workspace
   whose weekend is Friday and Saturday still got a grey Sunday, and changing the setting changed
   nothing on screen. There is no parameter for it; the class is simply applied. Neutralising it and
   painting our own from `OnCellRender` is the only way the drawing can follow the setting (D-076).

   `.k-nonwork-hour` is deliberately left alone although the vendor's stylesheet declares it in the
   same rule: that one is the hours outside the working day, which is a different statement and still
   a true one. */
.tp-calendar[b-em6k09zyxm]  .k-scheduler-nonwork {
    background-color: transparent;
}

/* Ours, from the workspace's weekend. Lighter than the closure band on purpose -- a closed day is
   something somebody decided and wrote a reason for, a Saturday is just a Saturday, and the two must
   not read as the same weight of statement. */
.tp-calendar[b-em6k09zyxm]  .tp-weekend {
    background-color: #f8f9fa;
}

/* The grid fills what is left of the window, and the page itself does not move.

   This is the measurement the component's Height="100%" leans on -- percent needs a parent with a
   definite height, and this is that parent. Two fixed pixel heights were tried first and both were
   wrong in the same way: 620px cut the afternoon off a working day, 980px fitted it and pushed the
   page into scrolling. Two scrollbars for one calendar, either way round.

   The subtraction is everything above the grid on that page: the heading, the two view buttons, the
   sentence under them, the filter row, and the scheduler's own toolbar. If that row ever grows, this
   number is the one thing to nudge -- and it is deliberately the only place a height is written down.
   It started at 17rem, which was a guess and left about five rems of white below the grid. 12rem was
   measured off a screenshot and overshot by a hair -- the page itself began to scroll, which is the
   one thing this rule exists to prevent. 13rem fitted; 10.5rem is that same fit after the sentence
   under the view buttons was taken off the page, which is where the last two and a half rems came
   from.

   A hair either way is all it can be, because the strip above the grid is not a fixed height -- the
   sentence under the view buttons wraps on a narrow window and the filter row wraps with it. When
   that happens the page scrolls a little, which is the honest failure of a fixed subtraction and the
   reason to prefer it anyway: the alternative is making the whole page a flex column, which reaches
   into the layout every other page shares.

   `min-height` so the calendar stays usable on a short window or a phone in landscape, where filling
   the viewport would leave a grid two hours tall. There the page may scroll, which is the right
   trade. */
.tp-calendar[b-em6k09zyxm] {
    height: calc(100vh - 10.5rem);
    min-height: 22rem;
}

/* A month does not scroll sideways.

   The vendor puts `overflow: auto` on the whole flex layout, which is right for a week -- the clock
   runs down the side and there is more of it than fits. In a month the columns are flexible and share
   whatever width there is, so a horizontal bar there means a rounding difference of a pixel or two
   and never content anybody could reach by scrolling to it. Hidden rather than left to appear and
   disappear with the window width.

   The vertical bar in the month is gone the other way round, by giving that view no fixed height at
   all -- see SchedulerHeight. A grid scrolling inside a page that also scrolls is two bars for one
   list. */
.tp-calendar[b-em6k09zyxm]  .k-scheduler-monthview {
    overflow-x: hidden;
}

/* A month shows a scrollbar only when there is something to scroll to.

   The vendor's own rule is `overflow-y: scroll` on the month's content -- not `auto` -- so the bar is
   there whether or not it leads anywhere. That is why one stayed behind after the calendar was made
   to fill the window: it was never about the height at all. `auto` is the whole fix.

   The slightly shorter row is the other half. Six weeks plus the day names come to a few pixels more
   than the window has, and 80px per row was the vendor's minimum rather than a considered size; 76px
   is what makes a six-week month fit without anything being cramped. It is a floor, not a height --
   a week with several appointments still grows past it and then the bar appears, correctly. */
.tp-calendar[b-em6k09zyxm]  .k-scheduler-monthview .k-scheduler-content {
    overflow-y: auto;
}

/* Do NOT make the month's rows share the height with `flex` on `.k-scheduler-row`.

   It was tried on 2026-09-03 to win back the last few pixels, and it flattened the whole month into
   a single strip of dates. The reason is the markup: in this view `.k-scheduler-row` exists on two
   nested levels -- an outer row holding a group cell, and inside that the row of seven days. A rule
   naming the class reaches both, and the outer one is not a week.

   The few pixels are not worth a second attempt at this. Where six weeks and their appointments come
   to more than the window holds, the grid scrolls, and that is honest. */
.tp-calendar[b-em6k09zyxm]  .k-scheduler-monthview .k-scheduler-body .k-scheduler-cell {
    min-height: 76px;
}

/* The week number in the toolbar, immediately after the date range (D-076).

   Quiet on purpose. It sits between the date and the view switch, both of which are things you press;
   a week number is not, and drawing it at the same weight would put a third button-looking thing in a
   row of two real ones. */
.tp-calendar[b-em6k09zyxm]  .k-scheduler-toolbar .tp-calendar-week,
.tp-calendar[b-em6k09zyxm]  .k-scheduler-toolbar .tp-calendar-span {
    color: var(--bs-secondary-color, #6c757d);
    font-size: .875rem;
    white-space: nowrap;
}

/* Naming the toolbar replaces the vendor's default one, and with it whatever pushed the view switch
   to the right-hand end. This puts it back.

   Anchored on the last child rather than on a class of the vendor's, and that is the second attempt:
   the first guessed at `.k-scheduler-views` and matched nothing, so the switch sat wherever it fell.
   The position is ours to know -- the tools are listed in this component's own markup, and the views
   tool is deliberately last there. Anything added to that toolbar goes *before* it; the comment in
   the markup says so, and this rule is why it matters. */
.tp-calendar[b-em6k09zyxm]  .k-scheduler-toolbar > *:last-child {
    margin-inline-start: auto;
}
/* /Components/Controls/CopyField.razor.rz.scp.css */
/* Two icons drawn, one shown, decided by a class the script adds -- so the script says what happened
   and this file says what that looks like. The same arrangement the password eye uses. */
.tp-copy-button .tp-copy-done[b-9az02h39iq] {
    display: none;
}

.tp-copy-button.tp-copied .tp-copy-mark[b-9az02h39iq] {
    display: none;
}

.tp-copy-button.tp-copied .tp-copy-done[b-9az02h39iq] {
    display: block;
}

/* Green only while it is saying something. A button that stays coloured has stopped reporting and
   started decorating. */
.tp-copy-button.tp-copied[b-9az02h39iq] {
    color: var(--bs-success, #198754);
    border-color: var(--bs-success, #198754);
}

/* The value is the point of the row, so it gets the width and a face that makes a token legible --
   an l and a 1 in an invitation link are worth telling apart. */
.tp-copy input[b-9az02h39iq] {
    font-family: var(--bs-font-monospace, monospace);
    font-size: .8125rem;
}
/* /Components/Controls/MonthDayCalendar.razor.rz.scp.css */
/* The month grid on a phone (D-098).

   Only ever drawn below the breakpoint, so nothing here is guarded by a media query: the page decides
   whether this component exists at all, and a stylesheet that repeated that decision would be a second
   place to change it. */

.tp-month-head[b-ya064bl9bk] {
    display: flex;
    align-items: center;
    gap: .25rem;
}

.tp-month-name[b-ya064bl9bk] {
    font-weight: 600;

    /* The month name is the one word in this row that changes length, and letting it push the arrows
       about would make them move as somebody steps through the year. */
    min-width: 9rem;
}

.tp-month-grid[b-ya064bl9bk] {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
}

.tp-month-weekday[b-ya064bl9bk] {
    text-align: center;
    font-size: .7rem;
    color: #6c757d;
    padding-bottom: .25rem;
}

.tp-month-day[b-ya064bl9bk] {
    position: relative;

    display: flex;
    align-items: center;
    justify-content: center;

    /* Square cells, whatever the screen is wide. A month that is taller than it is wide on one phone
       and the other way round on another is a month somebody has to re-learn. */
    aspect-ratio: 1;

    border: 0;
    border-radius: 50%;
    background: none;
    color: inherit;
    font-size: .9rem;
    line-height: 1;
    padding: 0;
}

/* The days of the months either side are drawn rather than left blank -- a grid with holes reads as
   broken -- but quietly, so the month one is looking at is the one that stands out. */
.tp-month-day.tp-outside[b-ya064bl9bk] {
    color: #adb5bd;
}

/* Today is named by a ring and the chosen day by a filled circle, so the two can be true at once:
   the ring stays visible under the fill's edge, and "today, and I am looking at it" is one of the
   commonest states this grid is in. */
.tp-month-day.tp-today[b-ya064bl9bk] {
    box-shadow: inset 0 0 0 1px var(--tp-link, #0d6efd);
}

.tp-month-day.tp-chosen[b-ya064bl9bk] {
    background-color: var(--tp-link, #0d6efd);
    color: #fff;
}

/* A dot and not a number: at this size a count is unreadable, and "is there anything" is the whole
   question a month grid is scanned for. Under the day's number rather than beside it, so a cell with
   two digits and a cell with one are the same shape. */
.tp-month-dot[b-ya064bl9bk] {
    position: absolute;
    bottom: .18rem;
    width: .25rem;
    height: .25rem;
    border-radius: 50%;
    background-color: var(--tp-link, #0d6efd);
}

.tp-month-day.tp-chosen .tp-month-dot[b-ya064bl9bk] {
    background-color: #fff;
}

/* The times line up in a column, which is what a day is read down. */
.tp-when[b-ya064bl9bk] {
    min-width: 3.5rem;
    font-variant-numeric: tabular-nums;
}
/* /Components/Controls/PasswordField.razor.rz.scp.css */
/* The box has to make room for the button, or the two overlap on a long password.

   `::deep` because the input is drawn by `InputText` and therefore carries that component's scope
   attribute rather than this one's -- the same rule the calendar's stylesheet leans on for the
   vendor's markup (D-028). Anchoring on `.tp-password`, which is ours, is what lets the rule reach it.

   Bootstrap's `form-floating` is not built to hold a second control, so the button is taken out of the
   flow entirely rather than fought with an `input-group`: an input group and a floating label disagree
   about which element owns the rounded corner, and the result looks broken at exactly the width where
   nobody is testing. */
.tp-password[b-hm5edcce3i] {
    position: relative;
}

.tp-password[b-hm5edcce3i]  .form-control {
    padding-right: 2.75rem;
}

/* Edge draws its own reveal button inside every password box, so the field showed two eyes side by
   side -- invisible in Chrome, which draws none, and therefore not noticed until somebody opened the
   sign-in page in Edge.

   Ours stays rather than Edge's, because Edge's exists only in Edge: keeping the browser's would mean
   the control is there for some visitors and missing for the rest, and the page would have to be
   designed for both cases at once. `::-ms-clear` goes with it -- same button family, same surprise.

   Prefixed selectors are invalid to engines that do not know them, and an unknown selector invalidates
   the whole rule it is in -- so these two get a rule of their own rather than being folded into the
   one above. */
.tp-password[b-hm5edcce3i]  .form-control::-ms-reveal,
.tp-password[b-hm5edcce3i]  .form-control::-ms-clear {
    display: none;
}

/* Centred on the box rather than on the wrapper: the validation message lives in the same wrapper and
   grows it downwards, and a button centred on all of that would drift below the field the moment a
   password was rejected. `top: 0` with the height of the floating box -- 3.5rem, Bootstrap's own -- is
   what keeps it still. */
.tp-password-eye[b-hm5edcce3i] {
    position: absolute;
    top: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 3.5rem;
    padding: 0;
    border: 0;
    background: none;
    color: var(--bs-secondary-color, #6c757d);
    cursor: pointer;

    /* Above the input so the click lands on the button, and above the floating label, which spans the
       whole width of the box and would otherwise swallow the pointer. */
    z-index: 3;
}

.tp-password-eye:hover[b-hm5edcce3i],
.tp-password-eye:focus-visible[b-hm5edcce3i] {
    color: var(--bs-body-color, #212529);
}

/* Which of the two icons is drawn. The class is put on by the script; everything else about the two
   states is here, so the script never touches a style. */
.tp-password-eye .tp-eye-shut[b-hm5edcce3i],
.tp-password.tp-password-shown .tp-password-eye .tp-eye-open[b-hm5edcce3i] {
    display: none;
}

.tp-password.tp-password-shown .tp-password-eye .tp-eye-shut[b-hm5edcce3i] {
    display: block;
}
/* /Components/Controls/PersonBadge.razor.rz.scp.css */
/* The circle stands where an icon stood, so it has to occupy exactly what the icon occupied or every
   label in the sidebar moves sideways by the difference. The icons are 1.25rem wide with 0.75rem of
   air after them; this is 1.5rem with 0.5rem, which is the same two rem in total and a slightly
   larger mark, because two letters need more room than one glyph. */

.tp-person-badge[b-bfz3ueih18] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 1.5rem;
    height: 1.5rem;
    margin-right: 0.5rem;
    border-radius: 50%;

    /* White at low opacity rather than the accent colour. The accent is the reader's own choice
       (AccentPicker) and the active row is already drawn as a white overlay -- an accent-coloured
       badge would either fight that highlight or vanish into it, depending on which accent somebody
       picked. A neutral mark is legible under all of them. */
    background-color: rgba(255, 255, 255, 0.22);
    color: white;

    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    line-height: 1;

    /* The letters are a picture of a person, not text somebody wants to select. */
    user-select: none;
}
/* /Components/Controls/PlanTable.razor.rz.scp.css */
.tp-plan-scroll[b-sxbif1bgjv] {
    /* A week of periods is wider than a phone and there is nothing to be done about that. It scrolls
       inside its own box so the page around it does not. */
    overflow-x: auto;
}

.tp-plan[b-sxbif1bgjv] {
    width: 100%;
    min-width: 46rem;
    border-collapse: separate;
    border-spacing: 2px;
    table-layout: fixed;
    font-size: .9rem;
}

.tp-plan th[b-sxbif1bgjv],
.tp-plan td[b-sxbif1bgjv] {
    padding: .4rem .5rem;
    text-align: center;
    vertical-align: middle;
    border-radius: .2rem;
}

.tp-plan thead th[b-sxbif1bgjv] {
    font-weight: 600;
    border-bottom: 2px solid var(--bs-border-color);
}

/* The period column is a label, not content: narrow, quiet, and lined up so the digits stack. */
.tp-plan-time[b-sxbif1bgjv] {
    width: 7.5rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
    color: var(--bs-secondary-color);
    background-color: transparent;
}

/* A washed version of the mark rather than the mark itself.

   The palette is built for marks -- small, saturated, legible against both grounds (D-057) -- and a
   cell filled with one of those at full strength is a block of colour with text fighting it. Mixed
   into white it reads the way the printed sheet does: the colour says which subject, the words stay
   black. One rule for all twenty-four, because the accent class publishes --tp-mark. */
.tp-plan-cell[b-sxbif1bgjv] {
    background-color: transparent;
    background-color: color-mix(in srgb, var(--tp-mark, transparent) 22%, #fff);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06);
}

/* Break, lunch, the start of the day: one thing said once, across the whole width. This is the row a
   scheduler cannot draw, because on a time axis there is no such thing as "all columns at once". */
.tp-plan-band[b-sxbif1bgjv] {
    background-color: var(--bs-tertiary-bg);
    font-style: italic;
    color: var(--bs-secondary-color);
}

/* A closed day: the same hatching the calendar draws over its closed stretches, so the two views say
   one thing in one language (D-064). It sits *under* the cell's own mark rather than replacing it --
   what somebody deliberately put into the holidays stays visible and stays coloured.

   The stripes are drawn rather than filled flat because flat grey reads as "no data", and a closed
   Tuesday is the opposite of that: it is a day about which something is known. */
.tp-plan-closed[b-sxbif1bgjv] {
    background-image: repeating-linear-gradient(
        45deg,
        rgba(0, 0, 0, .07) 0 4px,
        transparent 4px 9px);
}

.tp-plan-closed-head[b-sxbif1bgjv] {
    color: var(--bs-secondary-color);
}

/* Under the weekday, small: the day keeps its name, and the closure explains it. */
.tp-plan-closed-name[b-sxbif1bgjv] {
    display: block;
    font-weight: 400;
    font-style: italic;
    font-size: .8em;
    line-height: 1.2;
}

/* Under the name of the thing, small: who is on it (D-078).

   Deliberately the same shape as the closure under a weekday heading a few rules up -- a block, a
   size smaller, quieter than the line above it. Two different treatments for "a word explaining the
   line above" would be two things to learn where there is one idea.

   Not italic, though. The closure name is italic because a shut day is the table talking about
   itself; a person's name is content like the title above it, and italics on a name read as a
   qualification the name does not have. `opacity` rather than a colour, because the cell it sits in
   is washed with one of twenty-four marks and a fixed grey would sink into some of them. */
.tp-plan-lead[b-sxbif1bgjv] {
    display: block;
    font-size: .8em;
    line-height: 1.2;
    opacity: .7;
}

@media (max-width: 640px) {
    .tp-plan[b-sxbif1bgjv] {
        font-size: .8rem;
    }

    .tp-plan-time[b-sxbif1bgjv] {
        width: 5.5rem;
    }
}
/* /Components/Layout/CalendarMenu.razor.rz.scp.css */
/* The rows under the Kalender entry, in the tree's rhythm rather than Bootstrap's.

   Without this the rows arrive with `.nav-link`'s own half-rem of padding and no size of their own,
   which put the first calendar a blank row below the entry it belongs to -- far enough to read as a
   second, unrelated list rather than as what stands under Kalender.

   Said here a third time, after NavMenu and WorkspaceTree, and that is the cost of scoped stylesheets
   rather than an oversight: a scoped rule compiles to `.nav-item[b-xxxxx] …` and stops at the
   component that wrote the markup, so neither of the other two can reach these rows. The icons went
   to app.css when the second component needed them (D-053); three lines of rhythm are not yet worth
   the same move, and a global `.nav-item` rule would reach every sidebar entry including the tall
   ones above. */

.nav-item[b-1vqj1z46yi] {
    font-size: .9rem;
    padding-bottom: .1rem;
}

/* Indented to 1.1rem on top of the row's own 1rem, which lands the calendar mark exactly where a
   top-level node's mark lands in the tree: there the same offset is spent on the expander arrow. Two
   lists in one rail have to agree about what one level in looks like. */
.nav-item[b-1vqj1z46yi]  .nav-link {
    color: rgba(255, 255, 255, .85);
    padding: .15rem .25rem .15rem 1.1rem;
    border-radius: 4px;
}

.nav-item[b-1vqj1z46yi]  .nav-link:hover {
    color: #fff;
    background-color: rgba(255, 255, 255, .12);
}

.nav-item[b-1vqj1z46yi]  .nav-link.active {
    color: #fff;
    background-color: rgba(255, 255, 255, .22);
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* `.page`, `.sidebar` and the two of them at width now live in `app.css`. Two layouts draw this
   shell -- the application's and the one the Identity pages got when they were taken out of the
   workspace boundary (D-083) -- and a scoped stylesheet reaches only the component it belongs to. A
   second copy of a gradient is a gradient that will one day differ from the first. */

.top-row[b-hokbxqp8t2] {
    background-color: #f7f7f7;
    border-bottom: 1px solid #d6d5d5;
    justify-content: flex-end;
    height: 3.5rem;
    display: flex;
    align-items: center;
}

    .top-row[b-hokbxqp8t2]  a, .top-row[b-hokbxqp8t2]  .btn-link {
        white-space: nowrap;
        margin-left: 1.5rem;
        text-decoration: none;
    }

    .top-row[b-hokbxqp8t2]  a:hover, .top-row[b-hokbxqp8t2]  .btn-link:hover {
        text-decoration: underline;
    }

    .top-row[b-hokbxqp8t2]  a:first-child {
        overflow: hidden;
        text-overflow: ellipsis;
    }

@media (max-width: 767.98px) {
    .top-row[b-hokbxqp8t2] {
        justify-content: space-between;
    }

    .top-row[b-hokbxqp8t2]  a, .top-row[b-hokbxqp8t2]  .btn-link {
        margin-left: 0;
    }
}

@media (min-width: 768px) {
    .top-row[b-hokbxqp8t2] {
        position: sticky;
        top: 0;
        z-index: 1;
    }

    .top-row.auth[b-hokbxqp8t2]  a:first-child {
        flex: 1;
        text-align: right;
        width: 0;
    }

    .top-row[b-hokbxqp8t2], article[b-hokbxqp8t2] {
        padding-left: 2rem !important;
        padding-right: 1.5rem !important;
    }
}

#blazor-error-ui[b-hokbxqp8t2] {
    color-scheme: light only;
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss[b-hokbxqp8t2] {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }
/* /Components/Layout/MobileBar.razor.rz.scp.css */
/* The bottom navigation and the note button, both invisible above the breakpoint (D-098).

   768px is Taskplan's one breakpoint and stays one: the sidebar disappears at exactly the width this
   appears at, so there is no band in which both are on screen or neither is. Changing it means
   changing it in three places -- here, `app.css` and `NavMenu.razor.css` -- and D-098 says which.

   `::deep` on every rule that styles an entry, and that is not decoration: the entries are `NavLink`
   components, and scoped CSS marks only the elements written in this file. Without it the row was
   laid out correctly and each entry inside it was an ordinary blue underlined link -- which is
   exactly what the first attempt looked like on screen. The `<nav>` and the `<a>` of the note button
   are written here, so they need no `::deep`; the `<svg>` inside a NavLink does not either, because
   child content is still this component's markup. */

.tp-mobile-bar[b-83j9v1y1mt],
.tp-mobile-note[b-83j9v1y1mt] {
    display: none;
}

@media (max-width: 767.98px) {

    .tp-mobile-bar[b-83j9v1y1mt] {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 1030;

        display: flex;
        justify-content: space-around;
        align-items: stretch;

        background-color: #fff;
        border-top: 1px solid #dee2e6;

        /* The strip a phone keeps for its own home indicator. Without this the row of symbols sits
           under it and every tap lands on the wrong thing. */
        padding-bottom: env(safe-area-inset-bottom, 0);
    }

    .tp-mobile-bar[b-83j9v1y1mt]  .tp-mobile-item {
        flex: 1 1 0;
        min-width: 0;

        display: flex;
        align-items: center;
        justify-content: center;

        /* Fingers, not pointers: 3.25rem is above the 44px that every platform's own guidance names as
           the smallest thing worth aiming at, and without a caption underneath the symbol may have the
           whole height. */
        height: 3.25rem;

        text-decoration: none;
        color: #6c757d;
    }

    .tp-mobile-bar[b-83j9v1y1mt]  .tp-mobile-item:hover {
        text-decoration: none;
    }

    /* Outlines rather than solid shapes, and one weight for all four. A filled symbol beside a drawn
       one reads as "this one is selected" before anybody has looked at which one is. */
    .tp-mobile-bar[b-83j9v1y1mt]  .tp-mobile-item svg {
        width: 1.6rem;
        height: 1.6rem;
        fill: none;
        stroke: currentColor;
        stroke-width: 1.6;
        stroke-linecap: round;
        stroke-linejoin: round;
    }

    /* The current place is named by colour alone. A bar of four underlines would be a bar of four
       decorations; one symbol being darker is enough to answer "where am I", and it is the only
       difference left once the words are gone. */
    .tp-mobile-bar[b-83j9v1y1mt]  .tp-mobile-item.active {
        color: var(--tp-link, #0d6efd);
    }

    .tp-mobile-bar[b-83j9v1y1mt]  .tp-mobile-item.active svg {
        stroke-width: 2;
    }

    .tp-mobile-note[b-83j9v1y1mt] {
        position: fixed;
        right: 1rem;

        /* Above the row rather than on it: the row is four equal things and this is not one of them. */
        bottom: calc(4rem + env(safe-area-inset-bottom, 0px));
        z-index: 1031;

        display: flex;
        align-items: center;
        justify-content: center;
        width: 3.5rem;
        height: 3.5rem;
        border-radius: 50%;

        background-color: var(--tp-link, #0d6efd);
        color: #fff;
        box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .3);
    }

    .tp-mobile-note svg[b-83j9v1y1mt] {
        width: 1.75rem;
        height: 1.75rem;
        fill: none;
        stroke: currentColor;
        stroke-width: 2;
        stroke-linecap: round;
    }
}
/* /Components/Layout/NavMenu.razor.rz.scp.css */
.navbar-toggler[b-6u3gja5fbe] {
    appearance: none;
    cursor: pointer;
    width: 3.5rem;
    height: 2.5rem;
    color: white;
    position: absolute;
    top: 0.5rem;

    /* On the left since 2026-09-06, because the right of the top row belongs to the bell and because
       a hamburger on the left is where every phone has taught people to look (D-098). The brand keeps
       clear of it through the padding below. */
    left: 0.5rem;
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}

.navbar-toggler:checked[b-6u3gja5fbe] {
    background-color: rgba(255, 255, 255, 0.5);
}

.top-row[b-6u3gja5fbe] {
    min-height: 3.5rem;
    background-color: rgba(0,0,0,0.4);
}

.navbar-brand[b-6u3gja5fbe] {
    font-size: 1.1rem;
}

.bi[b-6u3gja5fbe] {
    display: inline-block;
    position: relative;
    width: 1.25rem;
    height: 1.25rem;
    margin-right: 0.75rem;
    top: -1px;
    background-size: cover;
}

.bi-house-door-fill-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}

.bi-plus-square-fill-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}

.bi-list-nested-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}

.bi-lock-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath d='M8 1a2 2 0 0 1 2 2v4H6V3a2 2 0 0 1 2-2zm3 6V3a3 3 0 0 0-6 0v4a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2zM5 8h6a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1z'/%3E%3C/svg%3E");
}

.bi-person-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-person' viewBox='0 0 16 16'%3E%3Cpath d='M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0Zm4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4Zm-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664h10Z'/%3E%3C/svg%3E");
}

.bi-person-badge-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-person-badge' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 2a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1h-3zM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0z'/%3E%3Cpath d='M4.5 0A2.5 2.5 0 0 0 2 2.5V14a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V2.5A2.5 2.5 0 0 0 11.5 0h-7zM3 2.5A1.5 1.5 0 0 1 4.5 1h7A1.5 1.5 0 0 1 13 2.5v10.795a4.2 4.2 0 0 0-.776-.492C11.392 12.387 10.063 12 8 12s-3.392.387-4.224.803a4.2 4.2 0 0 0-.776.492V2.5z'/%3E%3C/svg%3E");
}

.bi-person-fill-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-person-fill' viewBox='0 0 16 16'%3E%3Cpath d='M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3Zm5-6a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z'/%3E%3C/svg%3E");
}

/* Signing out, and the arrow points out of the door rather than into it.

   It was Bootstrap's `arrow-bar-left` -- a bar on the right with an arrow running away from it -- and
   read as "go back" beside a button that ends the session. Mirrored so the bar is on the left and the
   arrow leaves through it, which is the same picture every product uses for this.

   Mirrored rather than swapped for `arrow-bar-right`, whose path is a different set of numbers I would
   have had to copy correctly from somewhere. `translate(16, 0) scale(-1, 1)` flips the drawing about
   the middle of its own 16-wide box: provably the same icon, the other way round.

   This is a left-to-right picture and stays one. Should Taskplan ever speak a right-to-left language,
   the whole sidebar flips and this rule is one of the places that has to be revisited -- none of the
   five languages it speaks today is one. */
.bi-arrow-bar-right-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-arrow-bar-left' viewBox='0 0 16 16'%3E%3Cg transform='translate(16, 0) scale(-1, 1)'%3E%3Cpath d='M12.5 15a.5.5 0 0 1-.5-.5v-13a.5.5 0 0 1 1 0v13a.5.5 0 0 1-.5.5ZM10 8a.5.5 0 0 1-.5.5H3.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L3.707 7.5H9.5a.5.5 0 0 1 .5.5Z'/%3E%3C/g%3E%3C/svg%3E");
}

.nav-item[b-6u3gja5fbe] {
    font-size: 0.9rem;
    padding-bottom: 0.5rem;
}

    .nav-item:first-of-type[b-6u3gja5fbe] {
        padding-top: 1rem;
    }

    .nav-item:last-of-type[b-6u3gja5fbe] {
        padding-bottom: 1rem;
    }

    .nav-item[b-6u3gja5fbe]  .nav-link {
        color: #d7d7d7;
        background: none;
        border: none;
        border-radius: 4px;
        height: 3rem;
        display: flex;
        align-items: center;
        line-height: 3rem;
        width: 100%;

        /* Three quarters, not Bootstrap's whole rem, and the number is arithmetic rather than taste.
           The brand above sits at 1.75rem from the edge -- `ps-3` on its row plus the half gutter
           `.container-fluid` adds -- while `.nav-item px-3` gives these a rem and `.nav-link` its own
           rem on top, which put every entry a quarter out. The sidebar now has one left edge. */
        padding-left: .75rem;
    }

.nav-item[b-6u3gja5fbe]  a.active {
    background-color: rgba(255,255,255,0.37);
    color: white;
}

.nav-item[b-6u3gja5fbe]  .nav-link:hover {
    background-color: rgba(255,255,255,0.1);
    color: white;
}

.nav-scrollable[b-6u3gja5fbe] {
    display: none;
}

.navbar-toggler:checked ~ .nav-scrollable[b-6u3gja5fbe] {
    display: block;
}

@media (min-width: 768px) {
    .navbar-toggler[b-6u3gja5fbe] {
        display: none;
    }

    .nav-scrollable[b-6u3gja5fbe] {
        /* Never collapse the sidebar for wide screens */
        display: block;

        /* Allow sidebar to scroll for tall menus */
        height: calc(100vh - 3.5rem);
        overflow-y: auto;
    }
}

/* Everything below is only true on a narrow screen (D-098).

   What the drawer offers there is *not* the sidebar in a smaller frame: the inbox, the calendar and
   the settings have their own row at the bottom of the screen, and offering them twice would be the
   clutter D-042 is about. What is left is what the bottom row cannot hold -- the structure, the
   backend for whoever may see it, and signing out. */
@media (max-width: 767.98px) {
    /* The brand in the middle of the row, whatever stands to either side of it.

       Taken out of the flow rather than centred inside it, and that is the difference between "in the
       middle" and "in the middle of what is left": the hamburger is already absolute, the bell is not,
       and centring the brand between them would land it a little right of centre and move again the
       day the bell grows a badge. Half the row, minus half of itself, is the middle of the row. */
    .top-row[b-6u3gja5fbe] {
        position: relative;
    }

    .navbar-brand[b-6u3gja5fbe] {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        margin: 0;
    }

    /* With the brand out of the flow the bell is the only thing left in the row, and a lone item in a
       space-between row sits at the start. */
    .top-row .container-fluid[b-6u3gja5fbe] {
        justify-content: flex-end;
    }

    .tp-wide-only[b-6u3gja5fbe] {
        display: none;
    }
}

/* The mark carries its own dark card, which would disappear into the sidebar's dark blue. A hair of
   white behind it lifts it off, the same way the printed logo sits on paper. */
.tp-brand-mark[b-6u3gja5fbe] {
    border-radius: 5px;
    background-color: rgba(255, 255, 255, .92);
    padding: 2px;
}

.bi-calendar-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-calendar-week' viewBox='0 0 16 16'%3E%3Cpath d='M11 6.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1zm-3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1zm-5 3a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1zm3 0a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5v-1z'/%3E%3Cpath d='M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z'/%3E%3C/svg%3E");
}

/* The language picker on the signed-out sidebar. Deliberately quiet: it is a way out for somebody who
   ended up in a language they cannot read, not a control everybody has to step over. Closed it is one
   line; open it is four more.

   The geometry is the nav entries' -- same 0.9rem, same 3rem row, same icon and gap -- so the symbol
   and the word sit on the same two vertical lines as "Sign in" above. Only the colour is quieter,
   which is the whole difference between "aligned with" and "one of". */
.tp-language > summary[b-6u3gja5fbe] {
    display: flex;
    align-items: center;
    height: 3rem;
    font-size: 0.9rem;
    color: rgba(255, 255, 255, 0.55);
    cursor: pointer;

    /* The same inset the entries above use, for the same reason: `.nav-item px-3` gives a rem and this
       adds the rest, so the symbol lands on the sidebar's one left edge at 1.75rem. */
    padding: 0 .75rem;

    /* Both, because the two engines hide the default triangle differently and a stray marker beside
       our own caret is the sort of thing nobody notices until a screenshot. */
    list-style: none;
}

    .tp-language > summary[b-6u3gja5fbe]::-webkit-details-marker {
        display: none;
    }

    .tp-language > summary[b-6u3gja5fbe]::after {
        content: "\25be";
        margin-left: 0.4rem;
        font-size: 0.75rem;
    }

    .tp-language > summary:hover[b-6u3gja5fbe] {
        color: #fff;
    }

.tp-language[open] > summary[b-6u3gja5fbe]::after {
    content: "\25b4";
}

/* The summary's own inset, plus the icon's width and its gap: the languages start where the labels
   above start rather than where their symbols do. */
.tp-language .tp-language-list[b-6u3gja5fbe] {
    display: flex;
    flex-direction: column;
    padding: 0 1rem 0.5rem 2.75rem;
}

    .tp-language .tp-language-list a[b-6u3gja5fbe] {
        display: flex;
        align-items: center;
        height: 2rem;
        font-size: 0.9rem;
        color: rgba(255, 255, 255, 0.55);
        text-decoration: none;
    }

        .tp-language .tp-language-list a:hover[b-6u3gja5fbe] {
            color: #fff;
        }

.bi-translate-nav-menu[b-6u3gja5fbe] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-translate' viewBox='0 0 16 16'%3E%3Cpath d='M4.545 6.714 4.11 8H3l1.862-5h1.284L8 8H6.833l-.435-1.286zm1.634-.736L5.5 3.956h-.049l-.679 2.022z'/%3E%3Cpath d='M0 2a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v3h3a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-3H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zm7.138 9.995q.289.451.63.846c-.748.575-1.673 1.001-2.768 1.292.178.217.451.635.555.867 1.125-.359 2.08-.844 2.886-1.494.777.665 1.739 1.165 2.93 1.472.133-.254.414-.673.629-.89-1.125-.253-2.057-.694-2.82-1.284.681-.747 1.222-1.651 1.621-2.757H14V8h-3v1.047h.765c-.318.844-.74 1.546-1.272 2.13a6 6 0 0 1-.415-.492 2 2 0 0 1-.94.31'/%3E%3C/svg%3E");
}
/* /Components/Layout/NotificationBell.razor.rz.scp.css */
/* The bell sits in the sidebar's dark top row, so everything here is drawn for a dark ground --
   while the panel it opens is an ordinary light surface over the content, because that is where it
   is read. */

.tp-bell[b-65mi7qg6wd] {
    position: relative;
    display: flex;
    align-items: center;
}

.tp-bell-button[b-65mi7qg6wd] {
    position: relative;
    display: inline-flex;
    align-items: center;
    background: none;
    border: 0;
    padding: 0.25rem;
    line-height: 1;
    cursor: pointer;
    border-radius: 0.25rem;
    opacity: 0.85;
}

.tp-bell-button:hover[b-65mi7qg6wd],
.tp-bell-button:focus-visible[b-65mi7qg6wd] {
    background-color: rgba(255, 255, 255, 0.15);
    opacity: 1;
}

/* The same drawing the navigation entries use: a white Bootstrap glyph as a background image,
   `background-size: cover`, sized in rem. It began as the emoji bell, which was a mistake worth
   naming -- an emoji is a *coloured picture from another alphabet*, so it stood out as the one bright
   yellow thing on a screen of thin white line icons and read as an alert rather than as a control.
   The rule is repeated here rather than shared because `.bi` lives in NavMenu's scoped stylesheet and
   a scope attribute stops at the component boundary.

   A shade smaller than the navigation's 1.25rem on purpose: those name places you go to, this one is
   a control beside the brand, and it should sit in the row rather than lead it. */
.tp-bell-icon[b-65mi7qg6wd] {
    display: inline-block;
    width: 1.05rem;
    height: 1.05rem;
    background-size: cover;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-bell' viewBox='0 0 16 16'%3E%3Cpath d='M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2zM8 1.918l-.797.161A4.002 4.002 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4.002 4.002 0 0 0-3.203-3.92L8 1.917zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5.002 5.002 0 0 1 13 6c0 .88.32 4.2 1.22 6z'/%3E%3C/svg%3E");
}

/* The number, not a dot. "Something is waiting" is worth less than "three things are waiting" --
   the second tells somebody whether to open it now or after the meeting. */
.tp-bell-count[b-65mi7qg6wd] {
    position: absolute;
    top: -0.1rem;
    right: -0.2rem;
    min-width: 0.9rem;
    padding: 0 0.18rem;
    border-radius: 0.5rem;
    background-color: #d9480f;
    color: #fff;
    font-size: 0.62rem;
    font-weight: 600;
    line-height: 0.9rem;
    text-align: center;
}

/* Fixed rather than absolute: the sidebar is a narrow, scrolling column, and a panel positioned
   inside it would be clipped by the first ancestor that hides its overflow. Fixed takes it out of
   that entirely, at the cost of not following the button if the page scrolls -- which it cannot,
   because the top row is sticky. */
.tp-bell-panel[b-65mi7qg6wd] {
    position: fixed;
    top: 3.2rem;
    left: 0.5rem;
    /* As wide as its widest line and no wider, between two bounds. A fixed width made a panel of
       three short reminders look like an empty dialogue; `max-content` alone would let one long task
       name stretch it across the screen. The lower bound keeps the three buttons on one line. */
    width: max-content;
    min-width: 15rem;
    max-width: min(22rem, calc(100vw - 1rem));
    max-height: min(28rem, calc(100vh - 4rem));
    overflow-y: auto;
    z-index: 1050;
    background-color: #fff;
    color: #212529;
    border: 1px solid #d6d5d5;
    border-radius: 0.4rem;
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.2);
    padding: 0.5rem 0;
}

/* On a phone the bell is at the right end of the top row -- the brand is centred there -- so a panel
   pinned to the left would open across the screen from the control that opened it. Right-aligned
   instead, under the bell, which is where the eye already is. */
@media (max-width: 767.98px) {
    .tp-bell-panel[b-65mi7qg6wd] {
        left: auto;
        right: 0.5rem;
    }
}

.tp-bell-empty[b-65mi7qg6wd] {
    margin: 0;
    padding: 0.75rem 1rem;
    color: #6c757d;
}

.tp-bell-list[b-65mi7qg6wd] {
    list-style: none;
    margin: 0;
    padding: 0;
}

.tp-bell-entry[b-65mi7qg6wd] {
    padding: 0.6rem 1rem;
    border-bottom: 1px solid #eee;
}

.tp-bell-entry:last-child[b-65mi7qg6wd] {
    border-bottom: 0;
}

.tp-bell-name[b-65mi7qg6wd] {
    display: block;
    overflow-wrap: anywhere;
    font-weight: 600;
    color: #212529;
    text-decoration: none;
}

.tp-bell-name:hover[b-65mi7qg6wd] {
    text-decoration: underline;
}

.tp-bell-when[b-65mi7qg6wd] {
    font-size: 0.85rem;
    color: #6c757d;
    margin-top: 0.1rem;
}

.tp-bell-node[b-65mi7qg6wd]::before {
    content: " · ";
}

.tp-bell-actions[b-65mi7qg6wd] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.45rem;
}

.tp-bell-action[b-65mi7qg6wd] {
    background: none;
    border: 1px solid #ced4da;
    border-radius: 0.25rem;
    padding: 0.1rem 0.5rem;
    font-size: 0.85rem;
    color: #212529;
    cursor: pointer;
}

.tp-bell-action:hover[b-65mi7qg6wd] {
    background-color: #f1f3f5;
}

/* The one that ends it carries the weight, because it is the one that cannot be undone from here. */
.tp-bell-done[b-65mi7qg6wd] {
    border-color: #adb5bd;
    font-weight: 600;
}

.tp-bell-error[b-65mi7qg6wd] {
    margin: 0;
    padding: 0.5rem 1rem 0;
    color: #b02a37;
    font-size: 0.85rem;
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-2dk5sfvdfx],
.components-reconnect-repeated-attempt-visible[b-2dk5sfvdfx],
.components-reconnect-failed-visible[b-2dk5sfvdfx],
.components-pause-visible[b-2dk5sfvdfx],
.components-resume-failed-visible[b-2dk5sfvdfx],
.components-rejoining-animation[b-2dk5sfvdfx] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-2dk5sfvdfx],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-2dk5sfvdfx],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-2dk5sfvdfx],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-2dk5sfvdfx],
#components-reconnect-modal.components-reconnect-retrying[b-2dk5sfvdfx],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-2dk5sfvdfx],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-2dk5sfvdfx],
#components-reconnect-modal.components-reconnect-failed[b-2dk5sfvdfx],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-2dk5sfvdfx] {
    display: block;
}


#components-reconnect-modal[b-2dk5sfvdfx] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-2dk5sfvdfx 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-2dk5sfvdfx 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-2dk5sfvdfx 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-2dk5sfvdfx]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-2dk5sfvdfx 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-2dk5sfvdfx {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-2dk5sfvdfx {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-2dk5sfvdfx {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-2dk5sfvdfx] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-2dk5sfvdfx] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-2dk5sfvdfx] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-2dk5sfvdfx] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-2dk5sfvdfx] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-2dk5sfvdfx] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-2dk5sfvdfx] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-2dk5sfvdfx 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-2dk5sfvdfx] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-2dk5sfvdfx {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Layout/WorkspaceTree.razor.rz.scp.css */
/* Blazor scopes component CSS to its own component, so nothing from NavMenu.razor.css reaches these
   rows: without the rules below the links fall back to the browser's link colour, which is dark blue
   on a dark blue sidebar.

   Every rule that reaches inside a row goes through ::deep, and that is not a style preference -- it
   is the bug this file had. A scoped stylesheet compiles `.nav-link` to `.nav-link[b-xxxxx]`, and the
   attribute is only ever put on elements written in *this* component's markup. `<NavLink>` is a
   component: the <a> it renders carries our classes and none of our scope, so `.nav-link` and
   `.tp-archived` matched nothing at all, and every area in the tree was drawn in the browser's
   default blue while the entries above it in NavMenu were white. NavMenu had already learnt this and
   writes `.nav-item ::deep .nav-link`; this file did not.

   ::deep anchors on the row instead, which *is* our element -- `.nav-item[b-xxxxx] .nav-link` -- so
   it holds for anything inside the row no matter which component drew it. */

/* NavMenu gives its own entries this size and rhythm; its rules stop at the component boundary, so
   the tree has to say it again or the rows come out a size larger than the ones above them. */
.nav-item[b-93aj172led] {
    font-size: .9rem;
    padding-bottom: .1rem;
}

/* The tracking went with the capitals it was for: letter-spacing opens up uppercase, which needs it,
   and thins out ordinary words, which do not. */
.nav-item[b-93aj172led]  .tp-workspace-name {
    color: rgba(255, 255, 255, .8);
}

.nav-item[b-93aj172led]  .nav-link {
    color: rgba(255, 255, 255, .85);
    padding-left: .25rem;
    border-radius: 4px;
}

.nav-item[b-93aj172led]  .nav-link:hover {
    color: #fff;
    background-color: rgba(255, 255, 255, .12);
}

.nav-item[b-93aj172led]  .nav-link.active {
    color: #fff;
    background-color: rgba(255, 255, 255, .22);
}

/* Fixed width whether or not there is an expander, so names line up down the level. */
.nav-item[b-93aj172led]  .tp-tree-toggle {
    display: inline-block;
    width: 1.1rem;
    text-align: center;
    color: rgba(255, 255, 255, .7);
}

.nav-item[b-93aj172led]  .tp-add {
    color: rgba(255, 255, 255, .7);
    font-size: 1.05rem;
    line-height: 1;
}

.nav-item[b-93aj172led]  .tp-add:hover {
    color: #fff;
}

/* `min-width: 0` is the safety net, not decoration: without it a flex child refuses to shrink below
   the width of its content, so one long word in a button would widen the panel, the panel would widen
   the rail, and the whole sidebar would sit crooked. Nothing in here may decide how wide the sidebar
   is. */
.tp-create-panel[b-93aj172led] {
    background-color: rgba(255, 255, 255, .08);
    border-radius: 4px;
    min-width: 0;
    overflow-wrap: anywhere;
}

.tp-create-panel .form-label-small[b-93aj172led] {
    color: rgba(255, 255, 255, .75);
}

/* Bootstrap draws btn-link in link blue, which on this panel is dark on dark and barely legible.
   Abbrechen and Zurück are the quiet way out of the form and should look it: a weaker white that
   comes up to full on hover, rather than a colour that competes with the Create button beside it. */
.tp-create-panel .btn-link[b-93aj172led] {
    color: rgba(255, 255, 255, .7);
}

.tp-create-panel .btn-link:hover[b-93aj172led],
.tp-create-panel .btn-link:focus[b-93aj172led] {
    color: #fff;
}

/* Bootstrap draws the chevron as a dark SVG background image, which on this sidebar is dark on dark
   and effectively invisible -- the control looked like a text field. The image is redrawn in white
   rather than removed: without it the element reads as a box, and nobody clicks a box. */
.nav-item[b-93aj172led]  .tp-workspace-select {
    background-color: rgba(255, 255, 255, .12);
    border-color: rgba(255, 255, 255, .25);
    color: #fff;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* Dark text, and nothing else. The list the browser opens is drawn by the operating system, and it
   honours these properties one at a time rather than as a set: an attempt to colour it in the
   sidebar's blue was ignored for the background and obeyed for the text, so the selected row became
   white on white and could not be read at all.

   Half-styling a native popup is worse than not styling it. The closed control is ours -- dark, with
   a white chevron -- and the list stays the system's, which every platform draws legibly. When the
   Telerik wrappers arrive (D-028) this becomes a real component and the question disappears. */
.nav-item[b-93aj172led]  .tp-workspace-select option {
    color: #212529;
}

/* The navigation icons -- the base rule and the three masks -- used to live here and now live in
   app.css, under `.nav-item .tp-icon`. They had to move: the calendar list in the sidebar is a
   different component, so a rule scoped to this one could never reach it, and a second copy would
   have been two blocks to keep in step with one palette.

   The global selector carries two class names on purpose. `.tp-accent-red` sets a background-color
   of its own, and at one class each the later rule in the file would win -- which is exactly the
   trap the scope attribute used to save us from. Two classes outrank it without needing one. */

/* An archived node stays reachable but must never look like ordinary structure. The class sits on the
   <NavLink>, so this one in particular could never have worked without ::deep. */
.nav-item[b-93aj172led]  .tp-archived {
    text-decoration: line-through;
    opacity: .65;
}

/* The workspace row belongs with the entries above it, not with the tree below, and it was the one
   line in the sidebar that did neither: `px-3` alone put its mark at a rem while the brand sits at
   1.75rem and every nav entry now does too. Written out rather than left to `px-3` plus an override,
   because a padding fought with a utility class is a padding nobody can read off the markup.

   The mark itself is widened to the nav icons' footprint and pinned to the left of its box -- the mask
   is sized `contain` and centred, so a wider box would otherwise slide the glyph right by half the
   difference and undo the very alignment this is for. The drawn size does not change: `contain` fits
   the height, which stays. What it buys is the label beside it landing where "Calendar" and "Settings"
   begin, instead of three quarters of a rem short of them. */
.tp-workspace-row[b-93aj172led] {
    padding-left: 1.75rem;
    padding-right: 1rem;
}

.tp-workspace-row .tp-icon-workspace[b-93aj172led] {
    width: 1.25rem;
    margin-right: .75rem;
    -webkit-mask-position: left center;
    mask-position: left center;
}
/* /Components/Pages/Calendar.razor.rz.scp.css */
/* The two questions this page asks: what a new entry is called, and what "delete" should mean.

   Over the calendar rather than above it. Both are raised by something the reader did *in the grid* --
   a double-click at nine in the morning, a key pressed on an entry halfway down -- and an answer at
   the top of the page is an answer nobody sees. That is not a guess: it is what happened the first
   time somebody used it. */

.tp-ask-backdrop[b-qhb67y2noz] {
    position: fixed;
    inset: 0;
    z-index: 1040;

    /* Barely there. It is a question, not a modal that stops the world -- and the calendar behind it
       is the thing the reader is answering *about*, so dimming it away would be the wrong help. */
    background-color: rgba(0, 0, 0, 0.08);
}

.tp-ask[b-qhb67y2noz] {
    position: fixed;
    z-index: 1050;
    top: 30%;
    left: 50%;
    transform: translate(-50%, -50%);

    /* Wide enough for the sentence and the field side by side, narrow enough to read as a question
       about one thing rather than a second page. */
    width: min(38rem, calc(100vw - 2rem));

    box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.2);
}

/* Above the middle rather than in it: a question about a calendar is easier to answer while the
   calendar is still visible, and the rows people click are more often in the upper half. */
@media (max-height: 40rem) {
    .tp-ask[b-qhb67y2noz] {
        top: 50%;
    }
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* Centred in the page rather than pinned to the top: with no sidebar tree to balance it, a logo in
   the top-left corner of an empty page looks like something failed to load. */
.tp-welcome[b-c1stol4dr8] {
    max-width: 32rem;
    margin: 4rem auto;
}

.tp-welcome-logo[b-c1stol4dr8] {
    width: 100%;
    max-width: 20rem;
    height: auto;
}
/* /Components/Pages/WorkItems.razor.rz.scp.css */

/* Beside a page heading, so it needs a size of its own: at the default button size it read as a
   footnote next to something three times its height. The word is hidden on narrow screens, where the
   glyph alone has to do -- but on a desktop, where this was overlooked, it is spelled out. */
.tp-gear[b-2slwrsp991] {
    font-size: .95rem;
    line-height: 1.1;
    padding: .35rem .7rem;
}

.tp-gear span[aria-hidden][b-2slwrsp991] {
    font-size: 1.15rem;
    vertical-align: -.1rem;
}

@media (max-width: 640px) {
    .tp-gear-label[b-2slwrsp991] {
        display: none;
    }
}

/* The empty place where a note has no checkbox, because a thought is not something you tick off
   (D-040). It has to be exactly as wide as the control it stands in for -- Bootstrap draws
   .form-check-input at 1em -- or the column does not hold: at 1.5rem the note's type mark sat half a
   character to the right of every other row's, which is the sort of thing one sees without being able
   to say what is wrong. */
.tp-check-slot[b-2slwrsp991] {
    display: inline-block;
    flex: 0 0 auto;
    width: 1rem;
}

/* The type, in front of the name, the way the tree marks a node's kind (D-053). Inline data URIs
   rather than an icon font, for the same reason as there: a font that arrives late leaves a column of
   empty boxes behind it.

   Dimmed to .75 on purpose. These rows are read by their names; the mark is what the eye skips along,
   and at full black it would compete with the text it is meant to label. */
.tp-type-icon[b-2slwrsp991] {
    display: inline-block;
    flex: 0 0 auto;
    width: .95rem;
    height: .95rem;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    opacity: .75;
}

/* A sheet with a folded corner and two lines: a note is something written down and nothing more
   (D-040). It is the one type with no checkbox beside it, and the mark says why. */
.tp-type-note[b-2slwrsp991] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23495057'%3E%3Cpath fill-rule='evenodd' d='M3 1.5h6v4h4v9H3V1.5zM5 8h6v1H5V8zm0 2.5h5v1H5v-1z'/%3E%3C/svg%3E");
}

/* A flag, and emphatically not a ticked box -- see TypeIcon in the code-behind. The row already
   carries a checkbox two millimetres to the left, and a second box beside it said "done" about work
   nobody had started. */
.tp-type-task[b-2slwrsp991] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23495057'%3E%3Cpath d='M3.5 1.5h1v13h-1zM5 2h8l-2.2 3L13 8H5z'/%3E%3C/svg%3E");
}

/* A calendar, the same picture the Calendar entry uses in the sidebar. An appointment is the one
   work item whose whole point is when it happens. */
.tp-type-appointment[b-2slwrsp991] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23495057'%3E%3Cpath fill-rule='evenodd' d='M5 1h1.5v1.5H5V1zm4.5 0H11v1.5H9.5V1zM2.5 2.5h11v12h-11v-12zm1 3.5v7.5h9V6h-9z'/%3E%3C/svg%3E");
}

/* The rename pencil. Small on purpose: renaming is the rarer act now that the title opens the item,
   and it should not have the weight of a button people reach for by mistake. */
.tp-rename[b-2slwrsp991] {
    color: var(--bs-secondary-color);
    line-height: 1;
}

.tp-rename:hover[b-2slwrsp991] {
    color: var(--bs-body-color);
}

/* --- the tile view (D-056) ------------------------------------------------ */

/* Fills the width in whatever number of columns fits, rather than a fixed count: the same grid works
   on a phone and beside a wide list without a breakpoint to maintain. */
.tp-tile-grid[b-2slwrsp991] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
    gap: .6rem;
}

/* The accent classes set background-color, which on a tile would flood the whole card. Only the left
   edge takes the colour, so a marked tile still reads as a tile -- and an unmarked one keeps the
   ordinary border. */
.tp-tile[b-2slwrsp991] {
    position: relative;
    display: flex;
    align-items: stretch;
    min-height: 3.4rem;
    border: 1px solid var(--bs-border-color);
    border-left-width: 4px;
    border-left-color: var(--tp-mark, var(--bs-border-color));
    border-radius: .4rem;
    background-color: #fff !important;
    overflow: hidden;
}

.tp-tile:hover[b-2slwrsp991] {
    box-shadow: 0 1px 6px rgba(0, 0, 0, .12);
}

/* The whole face is the target, because the mode is one click per item. A button and an anchor are
   styled alike here: which of the two it is depends on whether the item has a verb at all. */
.tp-tile-face[b-2slwrsp991] {
    display: flex;
    align-items: flex-start;
    gap: .45rem;
    flex-grow: 1;
    padding: .55rem .5rem .55rem .6rem;
    border: 0;
    background: none;
    text-align: left;
    text-decoration: none;
    color: var(--bs-body-color);
    cursor: pointer;
}

.tp-tile-name[b-2slwrsp991] {
    font-size: .9rem;
    line-height: 1.25;
    overflow-wrap: anywhere;
}

/* Ticked, and still on screen. One click per item means mis-clicks, and a mis-click has to cost one
   click to undo rather than a search through a filter. */
.tp-tile-done .tp-tile-name[b-2slwrsp991] {
    text-decoration: line-through;
    color: var(--bs-secondary-color);
}

.tp-tile-done[b-2slwrsp991] {
    opacity: .72;
}

/* The way to everything the tile deliberately does not carry. Quiet, in the corner, and not in the
   way of the face -- which is the target that matters here. */
.tp-tile-open[b-2slwrsp991] {
    align-self: flex-start;
    padding: .35rem .5rem;
    color: var(--bs-secondary-color);
    text-decoration: none;
    font-size: 1.1rem;
    line-height: 1;
}

.tp-tile-open:hover[b-2slwrsp991] {
    color: var(--bs-body-color);
}

/* The heading holds its line even before the node has a name.

   Arriving from another page there is nothing to put in it -- the name is one round trip away -- and
   an empty h1 collapses to nothing, so everything below jumps up by the height of the title and back
   down when it arrives. It is seen even though nothing in it can be read, which is exactly what makes
   it hard to report. Reserving the line costs nothing and the jump is gone.

   `lh` is the line this heading would have had; the rem value above it is for browsers that do not
   know the unit yet and would otherwise reserve nothing at all. */
h1[b-2slwrsp991] {
    min-height: 2.5rem;
    min-height: 1lh;
}

/* When a row is. Quiet: it is read while scanning past, not looked up. */
.tp-when[b-2slwrsp991] {
    color: var(--bs-secondary-color);
    font-size: 0.875rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Only what is due and not done. A planned appointment in the past is over, not late. */
.tp-overdue[b-2slwrsp991] {
    color: var(--bs-danger);
    font-weight: 500;
}

/* The one control that carries everything not read at a glance. Positioned rather than floated so
   the list beneath it does not push the row it belongs to open. */
.tp-menu[b-2slwrsp991] {
    position: relative;
    flex: 0 0 auto;
}

.tp-menu-toggle[b-2slwrsp991] {
    line-height: 1;
    padding-inline: 0.55rem;
}

/* Hangs from the button's right edge and just below it, so it reads as belonging to the thing that
   was pressed rather than as a panel that appeared somewhere. */
.tp-menu-list[b-2slwrsp991] {
    position: absolute;
    top: calc(100% + 0.25rem);
    right: 0;
    z-index: 5;
    min-width: 11rem;
    padding: 0.25rem 0;
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

/* Bootstrap's .dropdown-item is written for anchors inside a .dropdown-menu, and a bare button gets
   none of it: no padding, no hover, and a browser's own button metrics instead. All of it said here,
   because half-inheriting a component's styling is how a menu ends up looking like a stack of words.
   The whole rule set rather than the gaps -- it is shorter than working out which half arrived. */
.tp-menu-list .dropdown-item[b-2slwrsp991] {
    display: block;
    width: 100%;
    padding: 0.375rem 1rem;
    text-align: left;
    font-size: 0.875rem;
    line-height: 1.5;
    white-space: nowrap;
    background: none;
    border: 0;
    color: var(--bs-body-color);
}

.tp-menu-list .dropdown-item:hover[b-2slwrsp991],
.tp-menu-list .dropdown-item:focus[b-2slwrsp991] {
    background-color: var(--bs-tertiary-bg);
}

/* Set apart rather than only coloured: it is the one entry in here that takes something out of
   circulation, and red alone is not a distinction somebody colour-blind can use. */
.tp-menu-list .dropdown-item.text-danger[b-2slwrsp991] {
    margin-top: 0.25rem;
    border-top: 1px solid var(--bs-border-color);
    padding-top: 0.5rem;
}

/* One thing and whatever hangs under it. */
.tp-entry[b-2slwrsp991] {
    position: relative;
}

.tp-dates-toggle[b-2slwrsp991] {
    padding-left: 2.6rem;
}

/* The line that says "these belong to the row above" -- the same device the tree in the sidebar
   uses, so the relationship is read rather than learnt. Drawn on the container and not per child,
   or a gap between two children would break it. */
.tp-children[b-2slwrsp991] {
    margin-left: 3.1rem;
    padding-left: 0.9rem;
    border-left: 1px solid var(--bs-border-color);
}

/* The short tick from the line to the row, which is what makes it read as a branch rather than as
   a quotation. Half the row's height, so it meets the text. */
.tp-child[b-2slwrsp991] {
    position: relative;
}

.tp-child[b-2slwrsp991]::before {
    content: "";
    position: absolute;
    left: -0.9rem;
    top: 50%;
    width: 0.6rem;
    border-top: 1px solid var(--bs-border-color);
}

/* The last child stops the line where its own tick is, instead of letting it run past the bottom
   into nothing. */
.tp-children .tp-child:last-child[b-2slwrsp991]::after {
    content: "";
    position: absolute;
    left: -0.95rem;
    top: calc(50% + 1px);
    bottom: -0.35rem;
    border-left: 1px solid var(--bs-body-bg);
}
