calendar

A HTML/PHP project for a self-hosted (family)-calendar.
Log | Files | Refs | README

style.css (20604B)


      1 :root {
      2   --polar1: #2E3440;
      3   --polar2: #3B4252;
      4   --polar3: #434C5E;
      5   --polar4: #4C566A;
      6   --snow1: #D8DEE9;
      7   --snow2: #E5E9F0;
      8   --snow3: #ECEFF4;
      9   --turquoise: #8FBCBB;
     10   --lightblue: #88C0D0;
     11   --midblue: #81A1C1;
     12   --darkblue: #5E81AC;
     13   --red: #BF616A;
     14   --orange: #D08770;
     15   --yellow: #EBCB8B;
     16   --green: #A3BE8C;
     17   --violet: #B48EAD;
     18 }
     19 
     20 *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
     21 html, body { height: 100%; overflow: hidden; }
     22 
     23 body {
     24   background: var(--polar1);
     25   font-family: 'Inter', system-ui, sans-serif;
     26   color: var(--snow1);
     27   font-size: 1rem;
     28   display: flex;
     29   flex-direction: column;
     30 }
     31 
     32 /* ── Topbar ── */
     33 .topbar {
     34   flex-shrink: 0;
     35   background: var(--polar2);
     36   border-bottom: 1px solid var(--polar3);
     37   z-index: 100;
     38 }
     39 .topbar-inner {
     40   height: 56px;
     41   padding: 0 1.5rem;
     42   display: flex;
     43   align-items: center;
     44   justify-content: space-between;
     45 }
     46 .topbar-name {
     47   font-size: 0.95rem;
     48   font-weight: 600;
     49   color: var(--snow3);
     50   text-decoration: none;
     51   letter-spacing: 0.02em;
     52 }
     53 .topbar-name:hover { color: var(--lightblue); }
     54 .topbar-right { display: flex; align-items: center; gap: 1.25rem; }
     55 .nav-link {
     56   color: var(--snow1);
     57   text-decoration: none;
     58   font-size: 0.875rem;
     59   font-weight: 400;
     60   letter-spacing: 0.03em;
     61   transition: color 0.15s;
     62 }
     63 .nav-link:hover { color: var(--lightblue); }
     64 .nav-link.signout:hover { color: var(--red); }
     65 .lang-switcher {
     66   display: inline-flex;
     67   align-items: center;
     68   background: var(--polar3);
     69   border-radius: 6px;
     70   padding: 3px;
     71   gap: 1px;
     72 }
     73 .lang-opt {
     74   background: none;
     75   border: none;
     76   border-radius: 4px;
     77   color: var(--snow1);
     78   cursor: pointer;
     79   font-family: inherit;
     80   font-size: 0.7rem;
     81   font-weight: 600;
     82   letter-spacing: 0.1em;
     83   line-height: 1;
     84   opacity: 0.4;
     85   padding: 4px 8px;
     86   transition: background 0.15s, color 0.15s, opacity 0.15s, box-shadow 0.15s;
     87 }
     88 .lang-opt.lang-active {
     89   background: var(--polar1);
     90   box-shadow: 0 1px 3px rgba(0,0,0,0.35);
     91   color: var(--lightblue);
     92   opacity: 1;
     93 }
     94 .lang-opt:not(.lang-active):hover { opacity: 0.75; }
     95 .topbar-home {
     96   display: flex;
     97   align-items: center;
     98   color: var(--snow1);
     99   opacity: 0.45;
    100   transition: opacity 0.15s, color 0.15s;
    101 }
    102 .topbar-home:hover { opacity: 1; color: var(--lightblue); }
    103 .topbar-home svg { width: 1rem; height: 1rem; }
    104 
    105 /* ── App body ── */
    106 .app-body {
    107   display: flex;
    108   flex: 1;
    109   min-height: 0;
    110   overflow: hidden;
    111   max-width: 1600px;
    112   width: 100%;
    113   margin: 0 auto;
    114 }
    115 
    116 /* ── Sidebar ── */
    117 .sidebar {
    118   width: 220px;
    119   flex-shrink: 0;
    120   background: var(--polar2);
    121   border-right: 1px solid var(--polar3);
    122   display: flex;
    123   flex-direction: column;
    124   overflow: hidden;
    125 }
    126 .sidebar-header {
    127   padding: 1.25rem 1rem 0.75rem;
    128   font-size: 0.7rem;
    129   font-weight: 500;
    130   letter-spacing: 0.14em;
    131   text-transform: uppercase;
    132   color: var(--snow1);
    133   opacity: 0.45;
    134 }
    135 .calendar-list {
    136   flex: 1;
    137   overflow-y: auto;
    138   padding: 0 0.5rem;
    139 }
    140 .calendar-item {
    141   display: flex;
    142   align-items: center;
    143   gap: 0.6rem;
    144   padding: 0.45rem 0.5rem;
    145   border-radius: 6px;
    146   cursor: pointer;
    147   transition: background 0.15s;
    148   user-select: none;
    149 }
    150 .calendar-item:hover { background: var(--polar3); }
    151 .calendar-item.selected { background: rgba(136,192,208,0.08); }
    152 
    153 .cal-dot {
    154   width: 10px;
    155   height: 10px;
    156   border-radius: 50%;
    157   flex-shrink: 0;
    158 }
    159 .cal-name {
    160   flex: 1;
    161   font-size: 0.875rem;
    162   color: var(--snow2);
    163   white-space: nowrap;
    164   overflow: hidden;
    165   text-overflow: ellipsis;
    166 }
    167 .cal-toggle {
    168   width: 16px;
    169   height: 16px;
    170   flex-shrink: 0;
    171   border-radius: 3px;
    172   border: 1.5px solid var(--polar4);
    173   background: transparent;
    174   cursor: pointer;
    175   display: flex;
    176   align-items: center;
    177   justify-content: center;
    178   transition: background 0.15s, border-color 0.15s;
    179 }
    180 .cal-toggle.visible {
    181   background: var(--lightblue);
    182   border-color: var(--lightblue);
    183 }
    184 .cal-toggle.visible::after {
    185   content: '';
    186   width: 9px;
    187   height: 5px;
    188   border-left: 2px solid var(--polar1);
    189   border-bottom: 2px solid var(--polar1);
    190   transform: rotate(-45deg) translateY(-1px);
    191   display: block;
    192 }
    193 
    194 .sidebar-actions {
    195   padding: 0.75rem 1rem 1.25rem;
    196   border-top: 1px solid var(--polar3);
    197 }
    198 .btn-new-cal {
    199   width: 100%;
    200   padding: 0.5rem 0.75rem;
    201   background: transparent;
    202   border: 1px solid var(--polar4);
    203   border-radius: 7px;
    204   color: var(--snow1);
    205   font-size: 0.8rem;
    206   font-family: inherit;
    207   cursor: pointer;
    208   display: flex;
    209   align-items: center;
    210   gap: 0.5rem;
    211   transition: border-color 0.15s, color 0.15s;
    212 }
    213 .btn-new-cal:hover { border-color: var(--lightblue); color: var(--lightblue); }
    214 .btn-new-cal svg { width: 14px; height: 14px; }
    215 
    216 /* ── Main calendar area ── */
    217 .calendar-main {
    218   display: flex;
    219   flex: 1;
    220   min-width: 0;
    221   overflow: hidden;
    222 }
    223 
    224 /* ── Monthly view ── */
    225 .monthly-view {
    226   display: flex;
    227   flex-direction: column;
    228   flex: 1 1 auto;
    229   min-width: 0;
    230   overflow: hidden;
    231 }
    232 
    233 /* Symmetric margins + max-width only when the daily panel is closed */
    234 .calendar-main:not(.daily-open) .monthly-view {
    235   max-width: 1000px;
    236   margin: 0 auto;
    237 }
    238 
    239 /* JS adds this class when remaining space < minimum usable width */
    240 .monthly-hidden { display: none !important; }
    241 .monthly-header {
    242   display: flex;
    243   align-items: center;
    244   justify-content: space-between;
    245   padding: 1.25rem 1.5rem 1rem;
    246   flex-shrink: 0;
    247 }
    248 .monthly-header-left {
    249   display: flex;
    250   align-items: center;
    251   gap: 0.75rem;
    252 }
    253 .monthly-title {
    254   font-family: 'EB Garamond', Georgia, serif;
    255   font-size: 1.5rem;
    256   font-weight: 600;
    257   color: var(--snow3);
    258 }
    259 .nav-btns { display: flex; gap: 0.4rem; }
    260 .nav-btn {
    261   width: 30px;
    262   height: 30px;
    263   border-radius: 6px;
    264   border: 1px solid var(--polar3);
    265   background: transparent;
    266   color: var(--snow1);
    267   cursor: pointer;
    268   display: flex;
    269   align-items: center;
    270   justify-content: center;
    271   transition: border-color 0.15s, color 0.15s;
    272 }
    273 .nav-btn:hover { border-color: var(--lightblue); color: var(--lightblue); }
    274 .nav-btn svg { width: 14px; height: 14px; }
    275 
    276 .weekday-row {
    277   display: grid;
    278   grid-template-columns: repeat(7, 1fr);
    279   padding: 0 1rem;
    280   flex-shrink: 0;
    281 }
    282 .weekday-label {
    283   text-align: center;
    284   font-size: 0.7rem;
    285   font-weight: 500;
    286   letter-spacing: 0.1em;
    287   text-transform: uppercase;
    288   color: var(--snow1);
    289   opacity: 0.35;
    290   padding: 0.3rem 0;
    291 }
    292 
    293 .day-grid {
    294   display: grid;
    295   grid-template-columns: repeat(7, 1fr);
    296   grid-auto-rows: 1fr;
    297   flex: 1;
    298   padding: 0 1rem 1rem;
    299   gap: 3px;
    300   min-height: 0;
    301 }
    302 .day-cell {
    303   border-radius: 8px;
    304   border: 1px solid transparent;
    305   padding: 0.4rem 0.5rem;
    306   cursor: pointer;
    307   display: flex;
    308   flex-direction: column;
    309   gap: 2px;
    310   transition: background 0.15s, border-color 0.15s;
    311   min-height: 0;
    312   overflow: hidden;
    313 }
    314 .day-cell:hover {
    315   background: var(--polar3);
    316   border-color: var(--polar4);
    317 }
    318 .day-cell.other-month { opacity: 0.3; }
    319 .day-cell.weekend { background: rgba(255,255,255,0.025); }
    320 .day-cell.today .day-number {
    321   background: var(--lightblue);
    322   color: var(--polar1);
    323   border-radius: 50%;
    324   width: 24px;
    325   height: 24px;
    326   display: flex;
    327   align-items: center;
    328   justify-content: center;
    329   font-weight: 600;
    330 }
    331 .day-cell.selected {
    332   background: rgba(136,192,208,0.08);
    333   border-color: var(--lightblue);
    334 }
    335 .day-number {
    336   font-size: 0.8rem;
    337   color: var(--snow2);
    338   line-height: 1;
    339   width: 24px;
    340   height: 24px;
    341   display: flex;
    342   align-items: center;
    343   justify-content: center;
    344 }
    345 
    346 /* ── Daily view ── */
    347 .daily-view {
    348   display: flex;
    349   flex-direction: column;
    350   flex: 0 0 0;
    351   min-width: 0;
    352   overflow: hidden;
    353   border-left: 1px solid transparent;
    354   opacity: 0;
    355   transition: flex-basis 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94),
    356               opacity 0.25s ease,
    357               border-color 0.35s;
    358 }
    359 .daily-open .daily-view {
    360   flex: 0 0 420px;
    361   max-width: 420px;
    362   opacity: 1;
    363   border-color: var(--polar3);
    364 }
    365 /* When monthly collapses, let daily fill all remaining width */
    366 .daily-open.monthly-collapsed .daily-view {
    367   flex: 1 1 auto;
    368   max-width: none;
    369 }
    370 
    371 .daily-header {
    372   display: flex;
    373   align-items: center;
    374   justify-content: space-between;
    375   padding: 1.25rem 1.5rem 1rem;
    376   flex-shrink: 0;
    377   border-bottom: 1px solid var(--polar3);
    378 }
    379 .daily-title {
    380   font-family: 'EB Garamond', Georgia, serif;
    381   font-size: 1.25rem;
    382   font-weight: 600;
    383   color: var(--snow3);
    384   flex: 1;
    385   min-width: 0;
    386   overflow: hidden;
    387   text-overflow: ellipsis;
    388   white-space: nowrap;
    389   margin-right: 0.75rem;
    390 }
    391 .btn-close {
    392   width: 28px;
    393   height: 28px;
    394   border-radius: 6px;
    395   border: 1px solid var(--polar3);
    396   background: transparent;
    397   color: var(--snow1);
    398   cursor: pointer;
    399   display: flex;
    400   align-items: center;
    401   justify-content: center;
    402   transition: border-color 0.15s, color 0.15s;
    403 }
    404 .btn-close:hover { border-color: var(--red); color: var(--red); }
    405 .btn-close svg { width: 14px; height: 14px; }
    406 
    407 /* All-day strip */
    408 .allday-section {
    409   display: flex;
    410   align-items: flex-start;
    411   border-bottom: 1px solid var(--polar3);
    412   padding: 0.35rem 0;
    413   flex-shrink: 0;
    414 }
    415 .allday-label {
    416   width: 56px;
    417   flex-shrink: 0;
    418   font-size: 0.65rem;
    419   color: var(--snow1);
    420   opacity: 0.35;
    421   text-align: right;
    422   padding-right: 0.75rem;
    423   padding-top: 0.3rem;
    424   text-transform: uppercase;
    425   letter-spacing: 0.05em;
    426   line-height: 1;
    427 }
    428 .allday-events {
    429   flex: 1;
    430   display: flex;
    431   flex-wrap: wrap;
    432   gap: 0.25rem;
    433   padding-left: 20px;
    434   margin-right: 1rem;
    435 }
    436 .allday-chip {
    437   border-radius: 4px;
    438   padding: 3px 8px;
    439   font-size: 0.72rem;
    440   font-weight: 500;
    441   cursor: pointer;
    442   white-space: nowrap;
    443   overflow: hidden;
    444   text-overflow: ellipsis;
    445   max-width: 100%;
    446   transition: filter 0.1s;
    447 }
    448 .allday-chip:hover { filter: brightness(1.15); }
    449 
    450 /* Toggle switch */
    451 .toggle-row {
    452   display: flex;
    453   align-items: center;
    454   justify-content: space-between;
    455 }
    456 .toggle-switch {
    457   position: relative;
    458   display: inline-block;
    459   width: 38px;
    460   height: 22px;
    461   flex-shrink: 0;
    462 }
    463 .toggle-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
    464 .toggle-slider {
    465   position: absolute;
    466   inset: 0;
    467   border-radius: 22px;
    468   background: var(--polar3);
    469   cursor: pointer;
    470   transition: background 0.2s;
    471 }
    472 .toggle-slider::after {
    473   content: '';
    474   position: absolute;
    475   width: 16px;
    476   height: 16px;
    477   border-radius: 50%;
    478   background: var(--snow1);
    479   top: 3px;
    480   left: 3px;
    481   transition: transform 0.2s;
    482 }
    483 .toggle-switch input:checked + .toggle-slider { background: var(--lightblue); }
    484 .toggle-switch input:checked + .toggle-slider::after { transform: translateX(16px); }
    485 
    486 .time-grid {
    487   flex: 1;
    488   overflow-y: auto;
    489   padding: 0;
    490 }
    491 .time-grid-inner {
    492   position: relative;
    493 }
    494 .time-row {
    495   display: flex;
    496   align-items: flex-start;
    497   height: 60px;
    498 }
    499 .time-label {
    500   width: 56px;
    501   flex-shrink: 0;
    502   font-size: 0.7rem;
    503   color: var(--snow1);
    504   opacity: 0.35;
    505   text-align: right;
    506   padding-right: 0.75rem;
    507   padding-top: 0.25rem;
    508   line-height: 1;
    509 }
    510 .time-slot {
    511   flex: 1;
    512   border-top: 1px solid var(--polar3);
    513   height: 100%;
    514   margin-right: 1rem;
    515   cursor: pointer;
    516   transition: background 0.1s;
    517 }
    518 .time-slot:hover { background: rgba(136,192,208,0.05); }
    519 
    520 .events-overlay {
    521   position: absolute;
    522   top: 0;
    523   left: 56px;
    524   right: 1rem;
    525   bottom: 0;
    526   pointer-events: none;
    527 }
    528 .event-block {
    529   position: absolute;
    530   left: 4px;
    531   right: 0;
    532   border-radius: 4px;
    533   padding: 2px 6px;
    534   font-size: 0.72rem;
    535   line-height: 1.3;
    536   overflow: hidden;
    537   cursor: pointer;
    538   pointer-events: all;
    539   border-left: 3px solid;
    540   display: flex;
    541   flex-direction: column;
    542 }
    543 .event-block:hover { filter: brightness(1.15); }
    544 .event-block-title {
    545   font-weight: 500;
    546   white-space: nowrap;
    547   overflow: hidden;
    548   text-overflow: ellipsis;
    549   flex-shrink: 0;
    550 }
    551 .event-block-desc {
    552   font-size: 0.67rem;
    553   opacity: 0.75;
    554   overflow: hidden;
    555   white-space: pre-wrap;
    556   word-break: break-word;
    557   margin-top: 1px;
    558 }
    559 
    560 /* ── Modal ── */
    561 .modal-overlay {
    562   position: fixed;
    563   inset: 0;
    564   background: rgba(0,0,0,0.55);
    565   z-index: 200;
    566   display: flex;
    567   align-items: center;
    568   justify-content: center;
    569   opacity: 0;
    570   pointer-events: none;
    571   transition: opacity 0.2s;
    572 }
    573 .modal-overlay.open {
    574   opacity: 1;
    575   pointer-events: all;
    576 }
    577 .modal {
    578   background: var(--polar2);
    579   border: 1px solid var(--polar3);
    580   border-radius: 12px;
    581   padding: 2rem;
    582   width: 420px;
    583   max-width: calc(100vw - 2rem);
    584   transform: translateY(12px);
    585   transition: transform 0.2s;
    586 }
    587 .modal-overlay.open .modal { transform: translateY(0); }
    588 
    589 .modal h2 {
    590   font-family: 'EB Garamond', Georgia, serif;
    591   font-size: 1.4rem;
    592   font-weight: 600;
    593   color: var(--snow3);
    594   margin-bottom: 1.5rem;
    595 }
    596 .form-group { margin-bottom: 1.1rem; }
    597 .form-label {
    598   display: block;
    599   font-size: 0.75rem;
    600   font-weight: 500;
    601   letter-spacing: 0.08em;
    602   text-transform: uppercase;
    603   color: var(--snow1);
    604   opacity: 0.55;
    605   margin-bottom: 0.4rem;
    606 }
    607 .form-input {
    608   width: 100%;
    609   padding: 0.55rem 0.75rem;
    610   background: var(--polar1);
    611   border: 1px solid var(--polar3);
    612   border-radius: 7px;
    613   color: var(--snow2);
    614   font-family: inherit;
    615   font-size: 0.9rem;
    616   outline: none;
    617   transition: border-color 0.15s;
    618 }
    619 .form-input:focus { border-color: var(--lightblue); }
    620 .form-input::placeholder { color: var(--snow1); opacity: 0.3; }
    621 
    622 .color-swatches {
    623   display: flex;
    624   gap: 0.5rem;
    625   flex-wrap: wrap;
    626 }
    627 .color-swatch {
    628   width: 28px;
    629   height: 28px;
    630   border-radius: 50%;
    631   cursor: pointer;
    632   border: 2px solid transparent;
    633   transition: border-color 0.15s, transform 0.15s;
    634 }
    635 .color-swatch:hover { transform: scale(1.1); }
    636 .color-swatch.selected { border-color: var(--snow3); }
    637 
    638 textarea.form-input {
    639   resize: vertical;
    640   min-height: 72px;
    641   line-height: 1.5;
    642 }
    643 
    644 .modal-wide { width: min(520px, 92vw); }
    645 
    646 .invite-list { display: flex; flex-direction: column; gap: 0.4rem; }
    647 .invite-row { display: flex; gap: 0.5rem; align-items: center; }
    648 .invite-row .form-input { flex: 1; }
    649 
    650 .member-row {
    651   display: flex;
    652   align-items: center;
    653   gap: 0.5rem;
    654   padding: 0.5rem 0;
    655   border-bottom: 1px solid var(--polar3);
    656   font-size: 0.875rem;
    657 }
    658 .member-username { flex: 1; color: var(--snow2); }
    659 
    660 .members-invite-section { margin-top: 0.25rem; }
    661 
    662 .btn-icon {
    663   width: 34px;
    664   height: 34px;
    665   border-radius: 7px;
    666   border: 1px solid var(--polar3);
    667   background: transparent;
    668   color: var(--snow1);
    669   cursor: pointer;
    670   display: flex;
    671   align-items: center;
    672   justify-content: center;
    673   flex-shrink: 0;
    674   font-size: 1.1rem;
    675   transition: border-color 0.15s, color 0.15s;
    676 }
    677 .btn-icon:hover { border-color: var(--lightblue); color: var(--lightblue); }
    678 .btn-icon.danger:hover { border-color: var(--red); color: var(--red); }
    679 
    680 .modal-actions {
    681   display: flex;
    682   justify-content: flex-end;
    683   gap: 0.6rem;
    684   margin-top: 1.75rem;
    685 }
    686 .btn {
    687   padding: 0.5rem 1.1rem;
    688   border-radius: 7px;
    689   font-family: inherit;
    690   font-size: 0.875rem;
    691   font-weight: 500;
    692   cursor: pointer;
    693   border: 1px solid var(--polar3);
    694   background: transparent;
    695   color: var(--snow1);
    696   transition: border-color 0.15s, color 0.15s, background 0.15s;
    697 }
    698 .btn:hover { border-color: var(--snow1); }
    699 .btn-primary {
    700   background: var(--lightblue);
    701   border-color: var(--lightblue);
    702   color: var(--polar1);
    703 }
    704 .btn-primary:hover { background: var(--turquoise); border-color: var(--turquoise); }
    705 
    706 /* ── Context menu ── */
    707 .ctx-menu {
    708   position: fixed;
    709   z-index: 300;
    710   background: var(--polar2);
    711   border: 1px solid var(--polar3);
    712   border-radius: 8px;
    713   padding: 0.3rem;
    714   min-width: 160px;
    715   box-shadow: 0 8px 24px rgba(0,0,0,0.4);
    716   display: none;
    717 }
    718 .ctx-menu.open { display: block; }
    719 .ctx-item {
    720   padding: 0.45rem 0.75rem;
    721   border-radius: 5px;
    722   font-size: 0.85rem;
    723   cursor: pointer;
    724   color: var(--snow1);
    725   transition: background 0.1s;
    726   display: flex;
    727   align-items: center;
    728   gap: 0.5rem;
    729 }
    730 .ctx-item:hover { background: var(--polar3); }
    731 .ctx-item.danger { color: var(--red); }
    732 .ctx-item.danger:hover { background: rgba(191,97,106,0.15); }
    733 
    734 /* ── Scrollbar ── */
    735 ::-webkit-scrollbar { width: 5px; }
    736 ::-webkit-scrollbar-track { background: transparent; }
    737 ::-webkit-scrollbar-thumb { background: var(--polar4); border-radius: 3px; }
    738 ::-webkit-scrollbar-thumb:hover { background: var(--snow1); opacity: 0.3; }
    739 
    740 /* ── Topbar left group ── */
    741 .topbar-left {
    742   display: flex;
    743   align-items: baseline;
    744   gap: 1.5rem;
    745 }
    746 
    747 /* ── Topbar back link ── */
    748 .topbar-back {
    749   font-size: 0.8rem;
    750   color: var(--snow1);
    751   opacity: 0.4;
    752   text-decoration: none;
    753   letter-spacing: 0.02em;
    754   transition: opacity 0.15s;
    755 }
    756 .topbar-back:hover { opacity: 0.8; }
    757 
    758 /* ── Sidebar toggle ── */
    759 .sidebar {
    760   transition: width 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
    761 }
    762 .sidebar.collapsed {
    763   width: 0 !important;
    764   overflow: hidden;
    765 }
    766 .btn-sidebar-toggle {
    767   width: 28px;
    768   height: 28px;
    769   border-radius: 6px;
    770   border: 1px solid var(--polar3);
    771   background: transparent;
    772   color: var(--snow1);
    773   cursor: pointer;
    774   display: flex;
    775   align-items: center;
    776   justify-content: center;
    777   flex-shrink: 0;
    778   transition: border-color 0.15s, color 0.15s;
    779 }
    780 .btn-sidebar-toggle:hover { border-color: var(--lightblue); color: var(--lightblue); }
    781 .btn-sidebar-toggle svg { width: 14px; height: 14px; }
    782 
    783 /* ── Sidebar sections ── */
    784 .sidebar-section { display: flex; flex-direction: column; }
    785 .sidebar-divider {
    786   height: 1px;
    787   background: var(--polar3);
    788   margin: 0.25rem 0.75rem;
    789   flex-shrink: 0;
    790 }
    791 
    792 /* ── Upcoming events ── */
    793 .upcoming-section {
    794   flex-shrink: 0;
    795   max-height: 260px;
    796   overflow-y: auto;
    797   padding-bottom: 0.15rem;
    798 }
    799 .upcoming-header {
    800   padding: 1.1rem 1rem 0.5rem;
    801   font-size: 0.68rem;
    802   font-weight: 500;
    803   letter-spacing: 0.14em;
    804   text-transform: uppercase;
    805   color: var(--snow1);
    806   opacity: 0.45;
    807 }
    808 .upcoming-item {
    809   display: flex;
    810   flex-direction: column;
    811   gap: 0.15rem;
    812   padding: 0.35rem 0.6rem 0.35rem 0.65rem;
    813   margin: 1px 0.5rem;
    814   border-radius: 5px;
    815   border-left: 3px solid transparent;
    816   cursor: pointer;
    817   transition: background 0.15s;
    818 }
    819 .upcoming-item:hover { background: var(--polar3); }
    820 .upcoming-title {
    821   font-size: 0.8rem;
    822   font-weight: 500;
    823   color: var(--snow2);
    824   white-space: nowrap;
    825   overflow: hidden;
    826   text-overflow: ellipsis;
    827   line-height: 1.3;
    828 }
    829 .upcoming-meta {
    830   font-size: 0.68rem;
    831   color: var(--snow1);
    832   opacity: 0.5;
    833   line-height: 1.2;
    834 }
    835 .upcoming-empty {
    836   padding: 0.2rem 1rem 0.6rem;
    837   font-size: 0.75rem;
    838   color: var(--snow1);
    839   opacity: 0.3;
    840   font-style: italic;
    841 }
    842 
    843 /* ── Daily header with add-event button ── */
    844 .daily-header-right {
    845   display: flex;
    846   align-items: center;
    847   gap: 0.5rem;
    848   flex-shrink: 0;
    849 }
    850 .btn-add-event {
    851   padding: 0.3rem 0.7rem;
    852   border-radius: 6px;
    853   border: 1px solid var(--polar3);
    854   background: transparent;
    855   color: var(--snow1);
    856   font-family: inherit;
    857   font-size: 0.78rem;
    858   cursor: pointer;
    859   transition: border-color 0.15s, color 0.15s;
    860   white-space: nowrap;
    861 }
    862 .btn-add-event:hover { border-color: var(--lightblue); color: var(--lightblue); }
    863 
    864 /* ── Event dots (monthly) ── */
    865 .event-dots {
    866   display: flex;
    867   gap: 2px;
    868   flex-wrap: wrap;
    869   padding: 2px 2px 0;
    870 }
    871 .event-dot {
    872   width: 5px;
    873   height: 5px;
    874   border-radius: 50%;
    875   flex-shrink: 0;
    876 }
    877 .event-dot-more {
    878   font-size: 0.55rem;
    879   color: var(--snow1);
    880   opacity: 0.45;
    881   line-height: 1;
    882   align-self: center;
    883 }
    884 
    885 /* ── Event modal ── */
    886 .event-modal { width: 480px; }
    887 .form-row {
    888   display: flex;
    889   gap: 0.75rem;
    890   margin-bottom: 1.1rem;
    891 }
    892 .form-row .form-group { flex: 1; margin-bottom: 0; }
    893 
    894 select.form-input {
    895   appearance: none;
    896   background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23D8DEE9' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    897   background-repeat: no-repeat;
    898   background-position: right 0.75rem center;
    899   cursor: pointer;
    900 }
    901 select.form-input option { background: var(--polar2); color: var(--snow1); }
    902 
    903 .attendee-list { display: flex; flex-direction: column; gap: 0.3rem; }
    904 .attendee-item {
    905   display: flex;
    906   align-items: center;
    907   gap: 0.5rem;
    908   font-size: 0.875rem;
    909   color: var(--snow1);
    910   cursor: pointer;
    911 }
    912 .attendee-item input[type="checkbox"] { accent-color: var(--lightblue); cursor: pointer; }
    913 
    914 /* ── Responsive ── */
    915 .btn-danger {
    916   background: transparent;
    917   border-color: var(--red);
    918   color: var(--red);
    919 }
    920 .btn-danger:hover { background: rgba(191,97,106,0.15); }
    921 
    922 /* ── Responsive ── */
    923 @media (max-width: 700px) {
    924   .sidebar { width: 0; overflow: hidden; }
    925   .sidebar.collapsed { width: 0 !important; }
    926   .sidebar:not(.collapsed) { width: 220px; }
    927   /* monthly-view hide/show when daily open is handled by JS ResizeObserver */
    928 }