/*
    The ribbon: a tab strip (32px) above a body (100px expanded, 40px collapsed).

    One global stylesheet rather than scoped CSS, because the collapsed view changes how every group and
    control inside the body lays out. Linked from the host's index.html as
    _content/Nidaros.Rpa.Server.Frontend.Ribbon/css/ribbon.css.

    The ribbon is a plain element, never an AntDesign <Header>: app.css gives every .ant-layout-header a
    fixed 80px height.
*/

/* On :root rather than .ribbon: AntDesign renders menus and tooltips at the end of the body. */
:root {
    --ribbon-accent: #00A3E0;
    --ribbon-accent-strong: #0097DB;
    --ribbon-icon: #0086B8;
    --ribbon-border: #A7DAEE;
    --ribbon-separator: #D1E8F0;
    --ribbon-hover: #E3F4FB;
    --ribbon-pressed: #D1E8F0;
    --ribbon-surface: #FFFFFF;
    --ribbon-text: rgba(0, 0, 0, 0.85);
    --ribbon-text-secondary: rgba(0, 0, 0, 0.55);
    --ribbon-text-disabled: #9AA7AD;
    --ribbon-error: #CF1322;
    --ribbon-error-surface: #FFF1F0;
}

.ribbon {
    flex: 0 0 auto;
    background: var(--ribbon-surface);
    border-bottom: 1px solid var(--ribbon-border);
    color: var(--ribbon-text);
}

/* The tab strip */

.ribbon-tabstrip {
    display: flex;
    align-items: stretch;
    gap: 2px;
    height: 32px;
    padding: 0 12px;
    border-bottom: 1px solid var(--ribbon-separator);
}

.ribbon-tab {
    margin-bottom: -1px;
    padding: 0 14px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--ribbon-text-secondary);
    font: inherit;
    font-size: 14px;
    cursor: pointer;
}

.ribbon-tab:hover {
    color: var(--ribbon-text);
}

.ribbon-tab-active {
    border-bottom-color: var(--ribbon-accent);
    color: var(--ribbon-accent-strong);
    font-weight: 500;
}

/* The expand/collapse button; .ribbon-toggle is the toggle control. */
.ribbon-view-toggle {
    display: grid;
    place-items: center;
    width: 32px;
    margin-left: auto;
    border: 0;
    border-radius: 4px;
    background: none;
    color: var(--ribbon-text-secondary);
    cursor: pointer;
}

.ribbon-view-toggle:hover {
    background: var(--ribbon-hover);
    color: var(--ribbon-text);
}

/* reset.css gives every svg max-width: 100%, which lets a flex line squeeze it to nothing. */
.ribbon-view-toggle svg {
    width: 20px;
    min-width: 20px;
    height: 20px;
    fill: currentColor;
}

.ribbon-tab:focus-visible,
.ribbon-view-toggle:focus-visible {
    outline: 2px solid var(--ribbon-accent);
    outline-offset: -3px;
}

/* The body and its groups */

.ribbon-body {
    display: flex;
    align-items: stretch;
    height: 100px;
    padding: 0 4px;
    overflow-x: auto;
    overflow-y: hidden;
}

.ribbon-group {
    display: flex;
    flex: 0 0 auto;
    flex-direction: column;
    padding: 4px 6px 0;
    border-right: 1px solid var(--ribbon-separator);
}

/* A group whose controls are all left out (not permitted, say) takes no room and draws no line. */
.ribbon-group:not(:has(.ribbon-control)) {
    display: none;
}

/* Controls fill columns of three rows: a large control takes a whole column, small ones stack. */
.ribbon-group-controls {
    display: grid;
    flex: 1;
    grid-auto-flow: column;
    grid-template-rows: repeat(3, minmax(0, 1fr));
    align-items: start;
    column-gap: 2px;
    min-height: 0;
}

.ribbon-group-label {
    height: 18px;
    color: var(--ribbon-text-secondary);
    font-size: 11px;
    line-height: 18px;
    text-align: center;
    white-space: nowrap;
}

.ribbon-error {
    display: inline-grid;
    place-items: center;
    align-self: center;
    width: 24px;
    height: 24px;
    margin: 0 6px;
    border-radius: 50%;
    background: var(--ribbon-error-surface);
    color: var(--ribbon-error);
    font-weight: 700;
}

/* Controls */

.ribbon-control {
    display: flex;
    min-width: 0;
}

.ribbon-control.ribbon-large {
    grid-row: span 3;
    align-self: stretch;
}

/* A small control is as wide as its own label, not as the widest one in its column. */
.ribbon-control.ribbon-small {
    justify-self: start;
}

/* AntDesign's tooltip and dropdown each wrap the control in an element of their own. */
.ribbon-tooltip-trigger,
.ribbon-dropdown-trigger {
    flex: 1 1 auto;
    min-width: 0;
}

.ribbon-face {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: 6px;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 4px;
    background: none;
    color: var(--ribbon-text);
    font: inherit;
    font-size: 12px;
    line-height: 1.2;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
}

.ribbon-face:hover {
    background: var(--ribbon-hover);
    color: var(--ribbon-text);
}

.ribbon-face:active {
    background: var(--ribbon-pressed);
}

.ribbon-face:focus-visible {
    outline: 2px solid var(--ribbon-accent);
    outline-offset: -2px;
}

.ribbon-icon {
    display: inline-flex;
    flex: 0 0 auto;
    width: 16px;
    min-width: 16px;
    height: 16px;
    color: var(--ribbon-icon);
    font-size: 16px;
    line-height: 0;
}

.ribbon-icon > svg {
    width: 100%;
    height: 100%;
}

/* An AntDesign icon; app.css gives every .anticon svg a fixed grey fill. */
.ribbon-icon .anticon svg {
    width: 1em;
    min-width: 1em;
    height: 1em;
    fill: currentColor;
}

.ribbon-large .ribbon-icon {
    width: 32px;
    min-width: 32px;
    height: 32px;
    font-size: 32px;
}

.ribbon-caret {
    display: inline-block;
    width: 10px;
    min-width: 10px;
    height: 10px;
    margin-left: 2px;
    color: var(--ribbon-text-secondary);
    vertical-align: middle;
}

.ribbon-caret > svg {
    width: 100%;
    height: 100%;
}

/* Large: the icon on top, the label below it on up to two lines. */
.ribbon-large .ribbon-face {
    flex-direction: column;
    justify-content: flex-start;
    gap: 4px;
    min-width: 56px;
    max-width: 86px;
    padding: 6px 6px 2px;
    text-align: center;
    white-space: normal;
}

.ribbon-large .ribbon-label {
    max-height: 2.4em;
    overflow: hidden;
    overflow-wrap: break-word;
}

/* A label of text alone ends in an ellipsis when it needs a third line. (A menu's label also holds its
   arrow, which -webkit-box would put on a line of its own in Firefox, so that one is only cut off.) */
.ribbon-button.ribbon-large .ribbon-label,
.ribbon-toggle.ribbon-large .ribbon-label,
.ribbon-checkbox.ribbon-large .ribbon-label {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
}

/* Small: the icon with the label beside it, one of three rows. */
.ribbon-small .ribbon-face {
    height: 24px;
    padding: 0 8px 0 4px;
}

/* A split control: the main part runs the command, the arrow part opens the menu. */
.ribbon-large.ribbon-split .ribbon-dropdown-trigger {
    flex-direction: column;
}

.ribbon-large.ribbon-split .ribbon-split-main {
    flex: 0 0 auto;
    padding-bottom: 2px;
    border-radius: 4px 4px 0 0;
}

.ribbon-large.ribbon-split .ribbon-split-arrow {
    padding-top: 2px;
    border-radius: 0 0 4px 4px;
}

.ribbon-small.ribbon-split .ribbon-split-main {
    border-radius: 4px 0 0 4px;
}

.ribbon-small.ribbon-split .ribbon-split-arrow {
    flex: 0 0 auto;
    padding: 0 4px;
    border-radius: 0 4px 4px 0;
}

.ribbon-small.ribbon-split .ribbon-split-arrow .ribbon-caret {
    margin-left: 0;
}

/* A pointed-at split control outlines both parts, so the two read as one control. */
.ribbon-split:not(.ribbon-disabled):hover .ribbon-dropdown-trigger {
    border-radius: 4px;
    box-shadow: inset 0 0 0 1px var(--ribbon-separator);
}

/* A toggle that is on */
.ribbon-checked .ribbon-face {
    background: var(--ribbon-pressed);
    box-shadow: inset 0 0 0 1px var(--ribbon-border);
}

/* Disabled: the tooltip's wrapper gets the pointer, so it can say why (see RibbonTooltip). */
.ribbon-disabled {
    cursor: not-allowed;
}

.ribbon-disabled .ribbon-face {
    color: var(--ribbon-text-disabled);
    pointer-events: none;
}

.ribbon-disabled .ribbon-icon {
    color: var(--ribbon-text-disabled);
    opacity: 0.55;
}

.ribbon-disabled .ribbon-caret {
    color: var(--ribbon-text-disabled);
}

.ribbon-disabled.ribbon-checked .ribbon-face {
    background: var(--ribbon-hover);
    box-shadow: inset 0 0 0 1px var(--ribbon-separator);
}

/* A custom slot */
.ribbon-custom {
    align-items: center;
    gap: 6px;
    font-size: 12px;
}

.ribbon-custom.ribbon-small {
    min-height: 24px;
}

.ribbon-custom.ribbon-large {
    flex-direction: column;
    justify-content: center;
    padding: 0 4px;
}

.ribbon-custom.ribbon-large .ribbon-label {
    order: 1;
}

.ribbon-custom-content {
    display: flex;
    align-items: center;
}

/* A select or a search box: a field with its label in front (small) or below (large). */
.ribbon-field {
    display: flex;
    flex: 1 1 auto;
    align-items: center;
    gap: 6px;
    min-height: 24px;
    font-size: 12px;
}

.ribbon-large .ribbon-field {
    flex-direction: column;
    justify-content: center;
    padding: 0 4px;
}

.ribbon-large .ribbon-field .ribbon-label {
    order: 1;
}

.ribbon-disabled .ribbon-field .ribbon-label {
    color: var(--ribbon-text-disabled);
}

/* The search box is AntDesign's small affix input; its icons are the text's secondary colour. */
.ribbon-search-box .ribbon-icon {
    width: 14px;
    min-width: 14px;
    height: 14px;
    color: var(--ribbon-text-secondary);
}

.ribbon-search-clear {
    display: grid;
    place-items: center;
    width: 16px;
    height: 16px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: none;
    color: rgba(0, 0, 0, 0.25);
    cursor: pointer;
}

.ribbon-search-clear:hover {
    color: rgba(0, 0, 0, 0.45);
}

.ribbon-search-clear svg {
    width: 12px;
    min-width: 12px;
    height: 12px;
}

/* A checkbox: a box in front of the label, filled with the accent and a check mark while it is on. */
.ribbon-checkbox-box {
    display: inline-grid;
    flex: 0 0 auto;
    place-items: center;
    width: 14px;
    min-width: 14px;
    height: 14px;
    border: 1px solid #D9D9D9;
    border-radius: 2px;
    background: var(--ribbon-surface);
    color: var(--ribbon-surface);
}

.ribbon-checkbox-box svg {
    width: 12px;
    min-width: 12px;
    height: 12px;
}

.ribbon-face:hover .ribbon-checkbox-box {
    border-color: var(--ribbon-accent);
}

.ribbon-checkbox-checked .ribbon-checkbox-box {
    border-color: var(--ribbon-accent);
    background: var(--ribbon-accent);
}

.ribbon-large .ribbon-checkbox-box {
    margin: 9px;
}

.ribbon-disabled .ribbon-checkbox-box {
    border-color: #D9D9D9;
    background: #F5F5F5;
    color: var(--ribbon-text-disabled);
}

/* Tooltips and menus, which AntDesign renders at the end of the body */

.ribbon-tooltip {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.ribbon-tooltip-heading {
    font-weight: 500;
}

.ribbon-menu-item-content {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.ribbon-menu-item-text {
    display: flex;
    flex-direction: column;
    line-height: 1.35;
}

/* Why a disabled entry is disabled: readable, where the entry itself is greyed out. */
.ribbon-menu-item-reason {
    color: var(--ribbon-text-secondary);
    font-size: 12px;
}

.ribbon-menu .ribbon-icon {
    width: 18px;
    min-width: 18px;
    height: 18px;
    font-size: 18px;
}

.ribbon-menu .ant-dropdown-menu-item-disabled .ribbon-icon {
    color: inherit;
    opacity: 0.55;
}

/* An entry that is a link or submits a form: the link or button covers the whole entry. */
.ribbon-menu-item-action,
.ribbon-menu-item-action:hover {
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    text-align: inherit;
    text-decoration: none;
    cursor: inherit;
}

.ribbon-menu-item-action::after {
    content: "";
    position: absolute;
    inset: 0;
}

.ribbon-menu-item-action:focus-visible {
    outline: none;
}

.ribbon-menu-item-action:focus-visible::after {
    outline: 2px solid var(--ribbon-accent);
    outline-offset: -2px;
}

/* An entry that is on: its icon pressed, or a check mark where it has none. */
.ribbon-menu-item-checked .ribbon-icon:not(.ribbon-menu-item-check) {
    border-radius: 2px;
    background: var(--ribbon-pressed);
    box-shadow: 0 0 0 2px var(--ribbon-pressed), 0 0 0 3px var(--ribbon-border);
}

.ribbon-menu-item-check {
    color: var(--ribbon-accent-strong);
}

/*
    The "…" menu: one entry per control the line had no room for, scrolling when they are many. Its height
    leaves room for the app header and the ribbon above it, so it always fits below the "…".
*/
.ribbon-overflow-menu {
    min-width: 200px;
    max-height: calc(100vh - 160px);
    overflow-y: auto;
}

/* Its entries come from many controls, so an entry without an icon keeps the icon's room, and the labels line up. */
.ribbon-overflow-menu .ribbon-menu-item-content:not(:has(> .ribbon-icon)) {
    padding-left: 26px;
}

/* A search box or a custom slot in the "…" menu: the same content, on a row of its own. */
.ribbon-overflow-field {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
    padding: 5px 12px;
    font-size: 12px;
}

.ribbon-overflow-field-label {
    color: var(--ribbon-text-secondary);
}

/* The collapsed (single-line) view: one row, no group labels; what doesn't fit is clipped. */

.ribbon-collapsed .ribbon-body {
    align-items: center;
    height: 40px;
    overflow: hidden;
}

.ribbon-collapsed .ribbon-group {
    flex-direction: row;
    align-items: center;
    height: 28px;
    padding: 0 4px;
}

/* A group with nothing left to show in this view takes no room either. */
.ribbon-collapsed .ribbon-group:not(:has(.ribbon-control:not(.ribbon-collapse-hide))) {
    display: none;
}

.ribbon-collapsed .ribbon-group-controls {
    grid-template-rows: none;
    align-items: center;
}

.ribbon-collapsed .ribbon-group-label {
    display: none;
}

.ribbon-collapsed .ribbon-control.ribbon-large {
    grid-row: auto;
    align-self: center;
}

.ribbon-collapsed .ribbon-face,
.ribbon-collapsed .ribbon-large .ribbon-face {
    flex-direction: row;
    gap: 6px;
    height: 28px;
    min-width: 0;
    max-width: none;
    padding: 0 8px 0 6px;
    white-space: nowrap;
}

.ribbon-collapsed .ribbon-large .ribbon-icon {
    width: 16px;
    min-width: 16px;
    height: 16px;
    font-size: 16px;
}

.ribbon-collapsed .ribbon-large .ribbon-label {
    display: inline;
    max-height: none;
}

.ribbon-collapsed .ribbon-large.ribbon-split .ribbon-dropdown-trigger {
    flex-direction: row;
}

.ribbon-collapsed .ribbon-large.ribbon-split .ribbon-split-main {
    padding: 0 4px 0 6px;
    border-radius: 4px 0 0 4px;
}

.ribbon-collapsed .ribbon-large.ribbon-split .ribbon-split-arrow {
    padding: 0 6px 0 4px;
    border-radius: 0 4px 4px 0;
}

.ribbon-collapsed .ribbon-small.ribbon-split .ribbon-split-arrow {
    padding: 0 4px;
}

.ribbon-collapsed .ribbon-custom {
    flex-direction: row;
    height: 28px;
}

.ribbon-collapsed .ribbon-custom .ribbon-label {
    order: 0;
}

.ribbon-collapsed .ribbon-field {
    flex-direction: row;
    height: 28px;
    padding: 0 4px;
}

.ribbon-collapsed .ribbon-field .ribbon-label {
    order: 0;
}

.ribbon-collapsed .ribbon-large .ribbon-checkbox-box {
    margin: 0;
}

/* Icon only: the label moves to the tooltip; a menu keeps its arrow. */
.ribbon-collapsed .ribbon-collapse-icon .ribbon-face {
    justify-content: center;
    min-width: 28px;
    padding: 0 6px;
}

.ribbon-collapsed .ribbon-collapse-icon .ribbon-label {
    display: none;
}

.ribbon-collapsed .ribbon-collapse-icon .ribbon-label:has(> .ribbon-caret) {
    display: inline;
}

.ribbon-collapsed .ribbon-collapse-icon .ribbon-label-text {
    display: none;
}

.ribbon-collapsed .ribbon-collapse-hide {
    display: none;
}

/*
    The collapsed view's overflow. ribbonOverflow.js marks the controls that don't fit, and the groups left
    with none showing, with data-ribbon-overflowed; they keep their room but aren't seen, and the "…" menu
    (RibbonOverflowMenu) at the line's right end offers them instead. Its button is always there to be
    measured, and only seen while something overflows; it covers whatever is left of the line behind it.
*/

.ribbon-overflow {
    display: none;
}

.ribbon-collapsed .ribbon-body {
    position: relative;
}

.ribbon-collapsed [data-ribbon-overflowed] {
    visibility: hidden;
}

.ribbon-collapsed .ribbon-overflow {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    display: flex;
    align-items: center;
    padding: 0 4px 0 3px;
    border-left: 1px solid var(--ribbon-separator);
    background: var(--ribbon-surface);
    visibility: hidden;
}

.ribbon-collapsed .ribbon-overflow-active {
    visibility: visible;
}

.ribbon-overflow .ribbon-face {
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    color: var(--ribbon-text-secondary);
}

.ribbon-overflow .ribbon-face svg {
    width: 18px;
    min-width: 18px;
    height: 18px;
}

/*
    The rows of a list the ribbon acts on: a click selects (AntDesign's own ant-table-row-selected shows it),
    a double click or Enter opens. A row with a page of its own is reached through its primary row link; a
    row without one takes the focus itself. Either shows the focus ring only for the keyboard.
*/

tr.selectable-row:focus {
    outline: none;
}

tr.selectable-row:focus-visible > td {
    box-shadow: inset 0 2px 0 var(--ribbon-accent), inset 0 -2px 0 var(--ribbon-accent);
}

tr.selectable-row:focus-visible > td:first-child {
    box-shadow: inset 2px 2px 0 var(--ribbon-accent), inset 0 -2px 0 var(--ribbon-accent);
}

tr.selectable-row:focus-visible > td:last-child {
    box-shadow: inset -2px 2px 0 var(--ribbon-accent), inset 0 -2px 0 var(--ribbon-accent);
}

/* A row link reads as the cell's text, and covers the whole cell (AntDesign gives a cell position: relative). */
.row-link,
.row-link:hover,
.row-link:focus,
.row-link:active {
    color: inherit;
    outline: none;
}

.row-link::after {
    content: "";
    position: absolute;
    inset: 0;
}

.row-link:focus-visible::after {
    outline: 2px solid var(--ribbon-accent);
    outline-offset: -2px;
}
