@import 'global'; html, body { height: 100%; margin: 0; } body { background-color: var(--background-color); /* TODO --foreground-color or similar */ } .root { display: grid; margin: 0; max-width: 100%; height: 100%; grid-template-columns: auto auto 20em; grid-template-rows: auto; grid-template-areas: "main main nav" "main main cal" "main main details" "main main events" "footer footer events"; /* main the graphical portion of both the wide and the table view */ > main { /* these allow the main area to shrink, so that all areas will fit the screen. It will however not shrink the elements, leading to our (desired) scrollbar */ min-width: 0; /* for wide */ min-height: 0; /* for tall */ /* apparently required if one wants to have multiple items within main, without it overflowing */ display: flex; flex-direction: column; .event:target { box-shadow: 1em 1em 0.5em gold, -1em -1em 0.5em gold, 1em -1em 0.5em gold, -1em 1em 0.5em gold; z-index: 1; } /* For new event button */ position: relative; /* add new event button */ > button { position: absolute; right: 2mm; bottom: 5mm; height: 1cm; width: 1cm; } } footer { margin: 0.5em; color: ray; font-size: 8pt; display: flex; justify-content: space-between; flex-direction: row; span { margin: 0 1em; white-space: nowrap; } } } @media (max-aspect-ratio: 3/4) { .root { grid-template-areas: "main main" "nav events" "cal events" "details events" ". events" "footer events"; grid-template-rows: 70% auto; grid-template-columns: 50% auto; footer { flex-direction: column; } } } .hidelink { color: inherit; text-decoration: none; } .hidden { display: none; } /* Change View ---------------------------------------- "Buttons" for changing between weekly and monthly layout */ .calnav { display: flex; flex-direction: column; padding-left: 2em; padding-right: 2em; } .change-view { display: flex; flex-direction: row; justify-content: space-between; padding-top: 1ex; padding-bottom: 1ex; } date-jump { > form { display: flex; } input { flex-grow: 2; margin-right: 1em; } button, a { /* Same as height, figure out way to force this */ width: 2.5em; } } /* button -------------------------------------------------- */ .btn { /* if a */ text-decoration: none; /* if button */ border: none; background-color: inherit; /* --- */ box-sizing: border-box; padding: 0.5em; background-color: $blue; color: white; display: flex; justify-content: center; align-items: center; /* move button slightly, to give illusion of 3D */ box-shadow: $btn-height $btn-height gray; &:active { transform: translate($btn-height, $btn-height); box-shadow: none; } } .simplesearch { display: flex; input[type=text] { flex-grow: 1; } } li > button { width: 100%; } /* Eventlist ---------------------------------------- The sidebar with all the events */ .eventlist { min-height: 0; overflow: auto; border-top: 3px solid $gray; /* mostly for long links */ word-break: break-word; scroll-behavior: smooth; .eventtext { border-bottom: 1px solid black; margin-top: 1em; border-left-style: solid; border-left-width: 6px; padding-left: 2px; } .eventtext { border-color: var(--color); &.tentative { border-left-style: dashed; } } } /* Text day ---------------------------------------- Each event within the eventlist */ .text-day { border-left: 2px solid black; border-top: 2px solid black; padding-left: 2px; margin-top: 1em; header { position: sticky; top: 0; background-color: var(--background-color); h2 { width: 100%; text-align: center; font-size: 14pt; } } } /* Small calendar ---------------------------------------- */ .smallcal { display: flex; justify-content: center; .nav { display: flex; flex-direction: column; justify-content: center; font-size: 150%; } } .smallcall-head { text-align: center; font-weight: bold; } /* Sass greatly discourages @import in favour of @use. @use however doesn't work for me. */ @import 'small-calendar'; /* Sliders ---------------------------------------- */ .sliders { label { padding-left: 1em; } input[type="range"] { width: 100%; margin: 0; } } @import 'slider_input'; /* Calendar List ---------------------------------------- The list of all the loaded calendars, along with their colors. */ .calendarlist li { font-size: 8pt; list-style-type: none; border-left-width: 1em; border-left-style: solid; border-color: var(--color); padding-left: 1ex; /* force to single line */ overflow: hidden; white-space: nowrap; } /* Caltable ---------------------------------------- */ .table-head { font-size: 200%; text-align: center; } .caltable { flex-grow: 10; display: grid; grid-template-columns: repeat(7, 1fr); /* grid template rows is generated inline in the HTML */ max-height: 100%; /* Apparently needed to ensure that parent can contain all its children */ min-height: 0; .thead { font-weight: bold; display: flex; align-items: center; justify-content: center; } .thead, .cal-cell { border: 1px solid $gray; } .cal-cell { overflow-y: auto; .event, vevent-block { font-size: 8pt; border-radius: 5px; padding: 2px; margin-top: 2px; margin-bottom: 2px; font-family: arial; box-sizing: border-box; } } .cal-cell-time { border-bottom: none; } .cal-cell-short { border-top: none } .longevents { border-bottom: none; border-top: none; position: relative; .event { margin: 0; /* TODO use other border rules */ border: 1px solid black; position: absolute; box-sizing: border-box; padding: 0; } } } .date-info { color: $gray; .day-number { padding: 2pt; } &.current .day-number { color: black; } } /* Weekly calendar ---------------------------------------- */ .calendar { width: 100%; height: 100%; display: flex; flex-grow: 2; } .clock { color: $gray; border-top: 1px dotted $gray; width: 100%; pointer-events: none; } .sideclock { padding: 0; grid-row: 3; position: relative; .day { border: 1px transparent; min-width: 0; } .clock { border-top: 1px dotted $gray; grid-row: 3; } } .days { display: grid; grid-template-rows: 4em 4em auto; grid-template-columns: 5ch auto; width: 100%; height: 100%; padding: 0; overflow-x: scroll; /* allow for popup placement */ position: relative; .meta { border-bottom: 2px solid $gray; grid-row: 1; } .events { grid-row: 3; } .event { border: 1px solid black; } .longevents { grid-row: 2; grid-column-start: 2; position: relative; } .week-indicator { grid-row: 1 / span 2; } .sideclock { grid-row: 3; } } .week-indicator { display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 200%; color: $gray; } .events { position: relative; border: 1px solid $gray; .event { width: 100%; &.generated { width: calc(100% * var(--editmode)); } &.zero-length { border-radius: 0 1cm 1cm 0; height: calc(100% * 1/24) !important; } &.continuing { border-bottom: none; background-image: linear-gradient(to top, #0007 0%,#FFF0 2em); } &.continued { border-top: none; background-image: linear-gradient(to bottom, #FFF7 0%,#FFF0 3em); } &.continued.continuing { border-top: none; border-bottom: none; background-image: linear-gradient(to bottom, #FFF7 0%, #FFF0 10%, #FFF0 90%, #0007 100%); } } } /* * This makes the borders of the object be part of the size. * Making placing it on the correct line much simpler. */ .clock, .eventlike, .days vevent-block { position: absolute; box-sizing: border-box; margin: 0; display: block; } .clocktext { z-index: 1; text-align: right; } .meta { display: flex; justify-content: center; align-items: center; position: relative; padding-left: 1em; padding-right: 1em; .dayname { position: absolute; left: 5px; top: 2px; color: $gray; } .daydate { white-space: nowrap; font-size: 150%; } } /* graphical block in the calendar */ vevent-block, .event { transition: 0.3s; font-size: var(--event-font-size); overflow: hidden; background-color: var(--color); color: var(--complement); // position: absolute; display: block; width: 100%; min-height: 1em; border: 1px solid black; /* backgroudn: blue; */ /* Event is not confirmed to happen */ &.tentative { border: 3px dashed black; } /* Event duration is not "busy" time */ &.transparent { background-image: linear-gradient(45deg, #EE617DFF 25%, #00000000 25%, #00000000 50%, #EE617DFF 50%, #EE617DFF 75%, #00000000 75%, #00000000 100%); background-size: 56px 56px; } &.generated { opacity: 40%; /* TODO only disable transitions for top/botom, and only * when dragging (not when updating through other means) */ transition: none; } &.repeating { float: left; font-size: 150%; } .location { display: block; font-size: 80%; font-style: italic; white-space: pre; } } .event-body { padding: 0; margin: 0; width: 100%; height: 100%; overflow: hidden; /* TODO This gets to large for really short events, placing the marker halfway outside the event body. */ .description { position: absolute; right: 1ex; bottom: 0; font-size: 200%; } } /* .zero-width-events .event { width: initial; padding: 0.5em; margin: 0.2em; border-radius: 1ex; position: relative; float: left; } */ .repeating { color: red; } .clear-input { font-family: arial; font-size: 200%; color: grey; padding: 0; background: none; border: none; cursor: pointer; } .eventtext { white-space: pre-line; font-size: 10pt; h3 { font-size: 12pt; border-bottom: 1px solid $gray; margin-bottom: 0; font-weight: 300; margin-top: 0; } .location { display: inline-block; vertical-align: text-top; } .last-modified, .rrule { display: flex; justify-content: right; text-align: right; font-size: 80%; color: $gray; padding-right: 1em; } .categories > a::after { content: "," } .categories > a:last-child::after { content: "" } .categories > a { margin-right: 1ch; } } .attach { max-width: 100%; max-height: 3cm; } /* */ .longevents { .event { border-radius: 1em; padding-left: 1em; height: 90%; &.continuing { border-right: none; border-radius: 1em 0 0 1em; } &.continued { border-left: none; border-radius: 0 1em 1em 0; } &.continued.continuing { border-radius: 0; } } } /* * All other CAL_ classes are generated by the backend. * NOTE Possibly move this there. */ .CAL_Generated { background-color: #55FF55; } .clock-0 { top: calc(100%/24 * 0); } .clock-2 { top: calc(100%/24 * 2); } .clock-4 { top: calc(100%/24 * 4); } .clock-6 { top: calc(100%/24 * 6); } .clock-8 { top: calc(100%/24 * 8); border-width: 2px; } .clock-10 { top: calc(100%/24 * 10); } .clock-12 { top: calc(100%/24 * 12); } .clock-14 { top: calc(100%/24 * 14); } .clock-16 { top: calc(100%/24 * 16); border-width: 2px; } .clock-18 { top: calc(100%/24 * 18); } .clock-20 { top: calc(100%/24 * 20); } .clock-22 { top: calc(100%/24 * 22); } .clock-24 { top: calc(100%/24 * 24); } /* Search page ---------------------------------------- */ .paginator > * { padding-left: 1em; display: inline-block; } .summary-line { display: inline-flex; > * { display: inline-block; padding-left: 1ch; padding-right: 1ch; } time { font-family: monospace; min-width: 18ch; } } .error { border: 3px solid red; background-color: pink; pre { padding: 1em; } } /* Popups ---------------------------------------- */ popup-element { display: none; position: absolute; z-index: 1000; &[active] { z-index: 1001; } /* ??? */ left: 10px; top: -50px; box-shadow: gray 10px 10px 10px; &[visible] { display: block; } > * { resize: both; /* This overflow: auto gives us the correct resize handle */ overflow: auto; /* TODO this doesn't work, since tabcount is sepparate fronm * popup... */ min-height: calc(var(--tabcount) * #{$tablabel-margin + $tablabel-height}); /* some form of sensible minimi and default size for the popup (s main area). */ min-width: 150px; width: 350px; height: 300px; } } .popup-control { cursor: grab; background-color: var(--color); display: flex; @if $popup-style == "left" { flex-direction: column; padding: 1.2ex; } @else { flex-direction: row-reverse; padding: 1ex; } button { display: block; background: $blue; color: white; border: none; box-shadow: $btn-height $btn-height gray; &:active { transform: translate($btn-height, $btn-height); box-shadow: none; } @if $popup-style == "left" { width: 9mm; height: 9mm; margin-bottom: 2mm; } @else { width: 7mm; height: 7mm; margin-left: 1mm; } } } .popup-root { display: flex; @if $popup-style == "left" { flex-direction: row; } @else { flex-direction: column; } } tab-group { background-color: #dedede; color: black; width: 100%; height: 100%; /* This overflow: auto gives us the correct rendering of the content */ overflow: auto; [role="tabpanel"] { padding: 1em; } [role="tablist"] { display: flex; flex-direction: column; position: absolute; left: 100%; margin: 0; padding: 0; [role="tab"] { height: $tablabel-height; margin-bottom: $tablabel-margin; width: 5ex; &:hover { width: 10ex; } transition: width 0.1s ease-in-out; border: 1px solid #ccc; border-radius: 0 5px 5px 0; background-color: #aeaeae; } [aria-selected="true"] { border-left: none; background-color: #dedede; } } } vevent-edit { select { max-width: 100%; } input { white-space: initial; border: 1px solid gray; max-width: 100%; } .eventtext { word-break: break-word; table { word-break: initial; font-size: 65%; } } .edit-form { label { display: block; } /* REG */ input[type='text'], textarea { width: 100%; } .newfield { width: 100%; display: flex; } .timeinput { } } } .checkboxes { display: grid; grid-template-rows: 1fr 1fr; justify-items: baseline; label {grid-row: 1;} input {grid-row: 2;} } vevent-dl { font-size: 80%; dl { display: grid; grid-template-columns: 1fr 1fr; } } #bar { width: calc(100% + 2em); height: 4px; background: blue; border-color: blue; left: -1em; } .plusminuschecked label { color: black; } .plusminuscheck:checked ~ label .plus { color: green; } .plusminuscheck:not(:checked) ~ label .minus { color: red; } .inline-edit { input { /* important since regular spec is much stronger...*/ /* [REG] */ width: initial !important; } } /* Other ---------------------------------------- */ .template { display: none; } .summary-line .square { margin-right: 1em; } .square { width: 1em; height: 1em; background-color: var(--color); } .side-by-side { display: flex; } /* Icalendar ---------------------------------------- */ /* Below is for styling embedded xcalendar components in the xhtml document. I can't find anything about if this is allowed according to any standard, but it seems to work. Firefox doesn't want to admit it, and shows nothing in the inspector, but the document renders fine. Vivaldi works fine in the inspector. */ icalendar { display: inline-block; padding-left: 1ch; font-family: monospace; font-size: xx-small; padding-left: 1ch; properties > * { display: block; } properties * { padding-right: 1ch; } /* All icalendar properties */ calscale::before { content: "calscale: "; } method::before { content: "method: "; } prodid::before { content: "prodid: "; } version::before { content: "version: "; } attach::before { content: "attach: "; } categories::before { content: "categories: "; } class::before { content: "class: "; } comment::before { content: "comment: "; } description::before { content: "description: "; } geo::before { content: "geo: "; } location::before { content: "location: "; } percent-complete::before { content: "percent-complete: "; } priority::before { content: "priority: "; } resources::before { content: "resources: "; } status::before { content: "status: "; } summary::before { content: "summary: "; } completed::before { content: "completed: "; } dtend::before { content: "dtend: "; } due::before { content: "due: "; } dtstart::before { content: "dtstart: "; } duration::before { content: "duration: "; } freebusy::before { content: "freebusy: "; } transp::before { content: "transp: "; } tzid::before { content: "tzid: "; } tzname::before { content: "tzname: "; } tzoffsetfrom::before { content: "tzoffsetfrom: "; } tzoffsetto::before { content: "tzoffsetto: "; } tzurl::before { content: "tzurl: "; } attendee::before { content: "attendee: "; } contact::before { content: "contact: "; } organizer::before { content: "organizer: "; } recurrence-id::before { content: "recurrence-id: "; } related-to::before { content: "related-to: "; } url::before { content: "url: "; } uid::before { content: "uid: "; } exdate::before { content: "exdate: "; } rdate::before { content: "rdate: "; } rrule::before { content: "rrule: "; } action::before { content: "action: "; } repeat::before { content: "repeat: "; } trigger::before { content: "trigger: "; } created::before { content: "created: "; } dtstamp::before { content: "dtstamp: "; } last-modified::before { content: "last-modified: "; } sequence::before { content: "sequence: "; } request-status::before { content: "request-status: "; } parameters { color: gray; /* icalendar parameters */ altrep::before { content: "altrep:"; } cn::before { content: "cn:"; } cutype::before { content: "cutype:"; } delegated-from::before { content: "delegated-from:"; } delegated-to::before { content: "delegated-to:"; } dir::before { content: "dir:"; } encoding::before { content: "encoding:"; } fmttype::before { content: "fmttype:"; } fbtype::before { content: "fbtype:"; } language::before { content: "language:"; } member::before { content: "member:"; } partstat::before { content: "partstat:"; } range::before { content: "range:"; } related::before { content: "related:"; } reltype::before { content: "reltype:"; } role::before { content: "role:"; } rsvp::before { content: "rsvp:"; } sent-by::before { content: "sent-by:"; } tzid::before { content: "tzid:"; } } /* special fields inside some properties */ period { start { content: "start:"; } end { content: "end:"; } duration { content: "duration:" } } recur { freq { content: "freq:"; } until { content: "until:"; } count { content: "count:"; } bymonth { content: "bymonth"; } byweekno { content: "byweekno"; } byyearday { content: "byyearday"; } bymonthday { content: "bymonthday"; } byday { content: "byday"; } byhour { content: "byhour"; } byminute { content: "byminute"; } bysecond { content: "bysecond"; } bysetpos { content: "bysetpos"; } } /* types */ date-time, date, until {color: purple;} text { color: green; } integer { color: blue; } unknown { color: red; } } /* vim:expandtab:softtabstop=4:shiftwidth=4: */