| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
- @tailwind base;
- @tailwind components;
- @tailwind utilities;
- @layer base {
- /* Hide native spinner buttons on every number input app-wide. The
- team prefers keyboard typing over the tiny, inconsistent UA
- controls. */
- input[type="number"]::-webkit-outer-spin-button,
- input[type="number"]::-webkit-inner-spin-button {
- -webkit-appearance: none;
- margin: 0;
- }
- input[type="number"] {
- -moz-appearance: textfield;
- appearance: textfield;
- }
- }
- @layer utilities {
- /* Phase 13: the Focus filter temporarily hides entire sw columns when the
- focused worker has no assignment on any visible row. Separate from the
- .hidden set driven by the Columns dropdown so clearing Focus restores
- the user's manual column picks. */
- .focus-auto-hidden {
- display: none;
- }
- }
- @layer components {
- /* Phase 15: big-screen / beamer presentation scope. Applied via
- views/sprints/present.php on the root <main>. Tightens typography
- and cell padding so the task table fits the viewport without
- horizontal scroll at 1920×1080; hides drag handles and per-row
- delete buttons (not meaningful during a group discussion). */
- .beamer-root table {
- table-layout: fixed;
- font-size: clamp(0.75rem, 0.95vw, 1.05rem);
- }
- .beamer-root td,
- .beamer-root th {
- padding: 0.25rem 0.35rem;
- }
- .beamer-root .handle,
- .beamer-root [data-delete-task],
- .beamer-root [data-task-menu-trigger] {
- display: none;
- }
- /* JS-driven toggle (sprint-planner.js): when the rendered task table
- is wider than the viewport, rotate worker-column headers to save
- horizontal space. Leaves non-worker headers (Task / Owner / Prio
- / Tot) untouched. */
- .beamer-vertical-headers thead th[data-sort-col^="sw-"] {
- writing-mode: vertical-rl;
- transform: rotate(180deg);
- padding: 0.5rem 0.25rem;
- }
- /* Phase 18: per-cell task-assignment status. The colour class lives
- on the <td> (so JS / filters can read data-status off the cell),
- but the visible tint is applied to the day input / read-only span
- inside — colouring just the <td> made the cell padding stripe a
- different colour from the field, which read as visual noise. The
- four .assign-status-* class names are interpolated server-side
- ("assign-status-<?= $st ?>"), so they're held in
- tailwind.config.js's safelist; otherwise the JIT prunes them. */
- .assign-status-zugewiesen { /* default: no tint */ }
- .assign-status-gestartet input[data-assign],
- .assign-status-gestartet > span.font-mono { background-color: theme('colors.yellow.200'); }
- .assign-status-abgeschlossen input[data-assign],
- .assign-status-abgeschlossen > span.font-mono { background-color: theme('colors.green.200'); }
- .assign-status-abgebrochen input[data-assign],
- .assign-status-abgebrochen > span.font-mono { background-color: theme('colors.red.200'); }
- .dark .assign-status-gestartet input[data-assign],
- .dark .assign-status-gestartet > span.font-mono { background-color: theme('colors.yellow.700'); }
- .dark .assign-status-abgeschlossen input[data-assign],
- .dark .assign-status-abgeschlossen > span.font-mono { background-color: theme('colors.green.700'); }
- .dark .assign-status-abgebrochen input[data-assign],
- .dark .assign-status-abgebrochen > span.font-mono { background-color: theme('colors.red.700'); }
- /* Cell popover — replaces the per-cell chevron status select.
- Body-attached, position: absolute (set in JS), shown to the
- right of the bound input/cell. Carries a 0..N slider (max
- configured via /settings → assignment_slider_max) and a
- column of status pills with coloured bullets. */
- .cell-popover {
- position: absolute;
- z-index: 50;
- min-width: 14rem;
- padding: 0.75rem;
- border-radius: 0.5rem;
- border: 1px solid theme('colors.slate.200');
- background-color: theme('colors.white');
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
- }
- .dark .cell-popover {
- border-color: theme('colors.slate.700');
- background-color: theme('colors.slate.800');
- }
- .cell-popover-grid {
- display: grid;
- grid-template-columns: auto 1fr;
- gap: 1rem;
- align-items: center;
- }
- .cell-popover-slider {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 0.4rem;
- min-width: 2.5rem;
- }
- /* Vertical slider — `writing-mode + direction: rtl` covers modern
- browsers (low at the bottom, high at the top); the WebKit
- `slider-vertical` appearance and the Firefox `orient="vertical"`
- attribute (set in JS) are belt-and-braces for older engines. */
- .cell-popover-slider input[type="range"] {
- writing-mode: vertical-lr;
- direction: rtl;
- -webkit-appearance: slider-vertical;
- appearance: slider-vertical;
- width: 1.5rem;
- height: 8rem;
- accent-color: theme('colors.slate.600');
- cursor: pointer;
- }
- .dark .cell-popover-slider input[type="range"] {
- accent-color: theme('colors.slate.400');
- }
- .cell-popover-value {
- text-align: center;
- font-family: theme('fontFamily.mono');
- font-size: 0.875rem;
- color: theme('colors.slate.700');
- }
- .dark .cell-popover-value {
- color: theme('colors.slate.200');
- }
- .cell-popover-status {
- display: flex;
- flex-direction: column;
- gap: 0.25rem;
- min-width: 9rem;
- }
- .cell-popover-status-btn {
- display: flex;
- align-items: center;
- gap: 0.5rem;
- padding: 0.25rem 0.5rem;
- border-radius: 4px;
- text-align: left;
- font-size: 0.875rem;
- color: theme('colors.slate.700');
- background-color: transparent;
- border: 1px solid transparent;
- cursor: pointer;
- }
- .dark .cell-popover-status-btn {
- color: theme('colors.slate.200');
- }
- .cell-popover-status-btn:hover {
- background-color: theme('colors.slate.100');
- }
- .dark .cell-popover-status-btn:hover {
- background-color: theme('colors.slate.700');
- }
- .cell-popover-status-btn.cell-popover-active {
- border-color: theme('colors.slate.300');
- background-color: theme('colors.slate.50');
- }
- .dark .cell-popover-status-btn.cell-popover-active {
- border-color: theme('colors.slate.600');
- background-color: theme('colors.slate.700');
- }
- .cell-popover-bullet {
- display: inline-block;
- width: 0.75rem;
- height: 0.75rem;
- border-radius: 9999px;
- flex-shrink: 0;
- }
- .cell-popover-bullet.bullet-zugewiesen {
- border: 1px solid theme('colors.slate.300');
- }
- .dark .cell-popover-bullet.bullet-zugewiesen {
- border-color: theme('colors.slate.600');
- }
- .cell-popover-bullet.bullet-gestartet { background-color: theme('colors.yellow.300'); }
- .cell-popover-bullet.bullet-abgeschlossen { background-color: theme('colors.green.300'); }
- .cell-popover-bullet.bullet-abgebrochen { background-color: theme('colors.red.300'); }
- .dark .cell-popover-bullet.bullet-gestartet { background-color: theme('colors.yellow.500'); }
- .dark .cell-popover-bullet.bullet-abgeschlossen { background-color: theme('colors.green.500'); }
- .dark .cell-popover-bullet.bullet-abgebrochen { background-color: theme('colors.red.500'); }
- /* Phase 22: per-task hamburger menu, details modal, click-to-pickup
- reorder indicator, description popover. All single body-attached
- nodes; the JS positions them with absolute coordinates. */
- /* Task hamburger popup — three flex panes:
- [ menu | info | flyout (hidden by default) ]
- Body-attached, positioned by JS to the right of the trigger and
- vertically centred on it (cellPopover positioning model). */
- .task-menu {
- position: absolute;
- z-index: 60;
- border-radius: 0.5rem;
- border: 1px solid theme('colors.slate.200');
- background-color: theme('colors.white');
- box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.12), 0 4px 6px -4px rgb(0 0 0 / 0.1);
- }
- .dark .task-menu {
- border-color: theme('colors.slate.700');
- background-color: theme('colors.slate.800');
- }
- .task-menu-inner {
- display: flex;
- align-items: stretch;
- }
- .task-menu-list {
- display: flex;
- flex-direction: column;
- gap: 0.1rem;
- padding: 0.4rem;
- min-width: 12rem;
- border-right: 1px solid theme('colors.slate.100');
- }
- .dark .task-menu-list {
- border-right-color: theme('colors.slate.700');
- }
- .task-menu-item,
- .task-menu-sub-item {
- display: flex;
- width: 100%;
- align-items: center;
- justify-content: space-between;
- gap: 0.5rem;
- padding: 0.4rem 0.6rem;
- border-radius: 4px;
- text-align: left;
- font-size: 0.875rem;
- color: theme('colors.slate.700');
- background-color: transparent;
- cursor: pointer;
- white-space: nowrap;
- }
- .dark .task-menu-item,
- .dark .task-menu-sub-item {
- color: theme('colors.slate.200');
- }
- .task-menu-item:hover,
- .task-menu-sub-item:hover {
- background-color: theme('colors.slate.100');
- }
- .dark .task-menu-item:hover,
- .dark .task-menu-sub-item:hover {
- background-color: theme('colors.slate.700');
- }
- .task-menu-item-active {
- background-color: theme('colors.slate.100');
- }
- .dark .task-menu-item-active {
- background-color: theme('colors.slate.700');
- }
- .task-menu-item-danger {
- color: theme('colors.red.600');
- }
- .dark .task-menu-item-danger {
- color: theme('colors.red.400');
- }
- .task-menu-divider {
- height: 1px;
- margin: 0.25rem 0.25rem;
- background-color: theme('colors.slate.100');
- }
- .dark .task-menu-divider {
- background-color: theme('colors.slate.700');
- }
- /* Right pane: read-only task info. */
- .task-menu-info {
- display: flex;
- flex-direction: column;
- gap: 0.4rem;
- padding: 0.6rem 0.75rem;
- width: 18rem;
- max-width: 22rem;
- font-size: 0.825rem;
- color: theme('colors.slate.700');
- }
- .dark .task-menu-info {
- color: theme('colors.slate.100');
- }
- .task-menu-info-title {
- font-weight: 600;
- font-size: 0.9rem;
- color: theme('colors.slate.800');
- word-break: break-word;
- }
- .dark .task-menu-info-title {
- color: theme('colors.slate.100');
- }
- .task-menu-info-desc {
- white-space: pre-wrap;
- word-break: break-word;
- max-height: 12rem;
- overflow-y: auto;
- }
- .task-menu-info-url {
- font-size: 0.8rem;
- word-break: break-all;
- }
- .task-menu-info-url-link {
- color: theme('colors.blue.700');
- text-decoration: underline;
- }
- .dark .task-menu-info-url-link {
- color: theme('colors.blue.300');
- }
- .task-menu-info-refs-head {
- margin-top: 0.2rem;
- font-size: 0.7rem;
- text-transform: uppercase;
- letter-spacing: 0.05em;
- color: theme('colors.slate.500');
- margin-bottom: 0.2rem;
- }
- .dark .task-menu-info-refs-head {
- color: theme('colors.slate.400');
- }
- .task-menu-info-refs-list {
- display: flex;
- flex-wrap: wrap;
- gap: 0.25rem;
- }
- .task-menu-info-ref-chip {
- display: inline-flex;
- align-items: center;
- gap: 0.25rem;
- padding: 0.1rem 0.4rem;
- border-radius: 9999px;
- border: 1px solid theme('colors.slate.200');
- background-color: theme('colors.slate.50');
- color: theme('colors.slate.600');
- font-size: 0.75rem;
- text-decoration: none;
- }
- .task-menu-info-ref-chip:hover {
- background-color: theme('colors.slate.100');
- }
- .dark .task-menu-info-ref-chip {
- border-color: theme('colors.slate.600');
- background-color: theme('colors.slate.700');
- color: theme('colors.slate.300');
- }
- .dark .task-menu-info-ref-chip:hover {
- background-color: theme('colors.slate.600');
- }
- /* Flyout — third column for the sprint chooser when Move/Copy is
- picked. Slides in to the right of the info pane. */
- .task-menu-flyout {
- display: flex;
- flex-direction: column;
- padding: 0.4rem;
- width: 12rem;
- border-left: 1px solid theme('colors.slate.100');
- background-color: theme('colors.slate.50');
- }
- .dark .task-menu-flyout {
- border-left-color: theme('colors.slate.700');
- background-color: theme('colors.slate.700');
- }
- .task-menu-flyout-head {
- font-size: 0.7rem;
- text-transform: uppercase;
- letter-spacing: 0.05em;
- color: theme('colors.slate.500');
- padding: 0.2rem 0.5rem 0.4rem;
- }
- .dark .task-menu-flyout-head {
- color: theme('colors.slate.300');
- }
- .task-menu-flyout-list {
- display: flex;
- flex-direction: column;
- gap: 0.1rem;
- max-height: 16rem;
- overflow-y: auto;
- }
- .task-menu-sub-empty {
- padding: 0.4rem 0.6rem;
- font-size: 0.8rem;
- font-style: italic;
- color: theme('colors.slate.500');
- }
- .dark .task-menu-sub-empty {
- color: theme('colors.slate.400');
- }
- .task-modal-overlay {
- position: fixed;
- inset: 0;
- z-index: 70;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 1rem;
- background-color: rgb(15 23 42 / 0.45);
- }
- .task-modal-panel {
- width: 100%;
- max-width: 32rem;
- border-radius: 0.5rem;
- background-color: theme('colors.white');
- border: 1px solid theme('colors.slate.200');
- box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.3);
- display: flex;
- flex-direction: column;
- overflow: hidden;
- }
- .dark .task-modal-panel {
- background-color: theme('colors.slate.800');
- border-color: theme('colors.slate.700');
- }
- .task-modal-header {
- padding: 0.75rem 1rem;
- border-bottom: 1px solid theme('colors.slate.200');
- background-color: theme('colors.slate.50');
- color: theme('colors.slate.800');
- }
- .dark .task-modal-header {
- background-color: theme('colors.slate.700');
- border-color: theme('colors.slate.700');
- color: theme('colors.slate.100');
- }
- .task-modal-body {
- padding: 1rem;
- font-size: 0.875rem;
- }
- .task-modal-footer {
- padding: 0.5rem 1rem 0.75rem;
- display: flex;
- justify-content: flex-end;
- gap: 0.5rem;
- border-top: 1px solid theme('colors.slate.100');
- background-color: theme('colors.slate.50');
- }
- .dark .task-modal-footer {
- background-color: theme('colors.slate.700');
- border-color: theme('colors.slate.700');
- }
- .task-pickup-active {
- background-color: theme('colors.amber.100') !important;
- outline: 2px dashed theme('colors.amber.400');
- outline-offset: -2px;
- }
- .dark .task-pickup-active {
- background-color: theme('colors.amber.900') !important;
- outline-color: theme('colors.amber.500');
- }
- .task-pickup-indicator {
- position: absolute;
- height: 2px;
- background-color: theme('colors.amber.500');
- z-index: 65;
- pointer-events: none;
- box-shadow: 0 0 0 1px rgb(255 255 255 / 0.5);
- }
- }
|