gitoriaLog in with ident

tickets

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commit752fbb7f752fbb7fdeploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre752fbb7f/styles.hl

16.9 KB

  1. // styles.hl — ALL of the app's CSS, served as /__hl/app.css. Components carry no Style
  2. // blocks: markup is domain tags (<ticket-board>, <ticket-state>, …), this file lays them out.
  3. //
  4. // TOKENS (ticket antcolony#3, mission 021): the WorldAPI palette + semantic tokens are declared in
  5. // `shared/tokens.hl` as hl:web css variables (`static colorText = var(light)`), hand-written, a
  6. // verbatim copy of loreana /media/STORAGE/projects/worldapi-tokens/tokens.hl (vendored like
  7. // plugins/; edit it THERE and cp it here). This file IMPORTS the tokens it uses and writes them as
  8. // members (`color = colorText`, `border = '1px solid ' + colorBorder`); hl:web names each token
  9. // after its member (--color-text), writes all of tokens.hl's tokens into the one :root and every
  10. // use as var(--color-text). The app sets only its accent (`colorAccent = var(…)` below, written
  11. // after the default, so it wins). hl:web does this itself since hybriel#39 (the mission-021 patch is gone).
  12. //
  13. // In a styles file a bare name is a TAG (camelCase → kebab: `ticketState` is
  14. // `ticket-state`), a quoted name is a selector written verbatim. MOBILE FIRST: every
  15. // rule is the phone's; the one min-width block adds the wide layout.
  16. import { var } from 'hl:web/css'
  17. import { purple, colorText, colorBackground, colorTextStrong, colorTextMuted, colorBackgroundSunken, colorAccentText, colorSurface, colorBorder, colorDanger, colorSuccess, colorAction, colorWarning } from './shared/tokens.hl'
  18. colorAccent = var(purple) // the app's accent: the only token this app sets
  19. '*,
  20. *::before,
  21. *::after' { boxSizing = 'border-box' }
  22. html { colorScheme = 'dark' }
  23. body { margin = '0' font = '16px/1.5 system-ui, sans-serif' color = colorText background = colorBackground }
  24. a { color = colorAccent textDecoration = 'none' }
  25. 'a:hover' { textDecoration = 'underline' }
  26. h1 { margin = '0' fontSize = '1.3rem' lineHeight = '1.3' color = colorTextStrong overflowWrap = 'anywhere' }
  27. h2 { margin = '0 0 .5rem' fontSize = '1rem' color = colorTextStrong }
  28. time { color = colorTextMuted fontSize = '.85rem' whiteSpace = 'nowrap' }
  29. 'input,
  30. textarea,
  31. select' { font = 'inherit' width = '100%' padding = '.5rem .7rem' color = colorTextStrong background = colorBackgroundSunken border = '1px solid ' + colorBorder borderRadius = '.4rem' }
  32. 'input:focus,
  33. textarea:focus,
  34. select:focus' { outline = '2px solid ' + colorAccent outlineOffset = '1px' }
  35. textarea { resize = 'vertical' minHeight = '4.5rem' }
  36. label { display = 'grid' gap = '.25rem' fontSize = '.9rem' color = colorTextMuted }
  37. button { font = 'inherit' fontWeight = '600' padding = '.55rem 1.1rem' color = colorAccentText background = colorAccent border = '0' borderRadius = '.4rem' cursor = 'pointer' justifySelf = 'start' }
  38. 'button:hover' { filter = 'brightness(1.1)' }
  39. // ---- the shell ---------------------------------------------------------------------------
  40. applicationHeader { position = 'sticky' top = '0' zIndex = '5' display = 'flex' flexWrap = 'wrap' alignItems = 'center' gap = '.5rem 1rem' padding = '.6rem 1rem' background = colorBackgroundSunken borderBottom = '1px solid ' + colorBorder }
  41. 'application-header .brand' { fontWeight = '800' fontSize = '1.15rem' color = colorAccent marginRight = 'auto' }
  42. 'application-header nav' { display = 'flex' gap = '1rem' }
  43. 'application-header nav a' { color = colorText }
  44. inboxBadge { display = 'inline-block' marginLeft = '.35rem' padding = '0 .45rem' borderRadius = '999px' fontSize = '.8rem' fontWeight = '700' color = colorAccentText background = colorAccent }
  45. main { maxWidth = '60rem' margin = '0 auto' padding = '1rem' }
  46. // ---- the login, top right (ticket #7): ident's selector (its shadow DOM in ident's design,
  47. // restyled to tickets' accent through its custom properties), the login button, who you are
  48. userBox { display = 'flex' flexWrap = 'wrap' alignItems = 'center' justifyContent = 'flex-end' gap = '.4rem .6rem' marginLeft = 'auto' maxWidth = '100%' }
  49. identSelector { '--ident-accent' = colorAccent '--ident-accent-text' = colorAccentText '--ident-background' = colorSurface '--ident-border' = colorBorder '--ident-font' = '600 .9rem/1.4 system-ui, sans-serif' }
  50. 'ident-selector::part(button)' { padding = '.35rem .8rem' }
  51. 'ident-selector::part(status)' { padding = '.35rem .8rem' }
  52. '#whoami' { fontWeight = '600' color = colorTextStrong overflowWrap = 'anywhere' }
  53. 'a.button' { display = 'inline-block' fontWeight = '600' fontSize = '.9rem' padding = '.35rem .8rem' color = colorAccent border = '1px solid ' + colorAccent borderRadius = '.4rem' }
  54. 'a.button:hover' { textDecoration = 'none' background = colorSurface }
  55. 'button.quiet' { color = colorText background = 'transparent' border = '1px solid ' + colorBorder padding = '.35rem .8rem' fontSize = '.9rem' }
  56. 'button.danger' { color = colorDanger borderColor = colorDanger }
  57. namePrompt { display = 'block' maxWidth = '60rem' margin = '1rem auto 0' padding = '0 1rem' }
  58. '#nameform' { display = 'grid' gap = '.5rem' padding = '.8rem' background = colorSurface border = '1px solid ' + colorAccent borderRadius = '.5rem' }
  59. '.banner' { maxWidth = '60rem' margin = '.8rem auto 0' padding = '0 1rem' }
  60. '.hint' { margin = '0' fontSize = '.9rem' color = colorTextMuted }
  61. '.muted' { margin = '0' fontSize = '.9rem' color = colorTextMuted }
  62. // ---- /you: the account and the API tokens ---------------------------------------------------
  63. youView { display = 'grid' gap = '1.2rem' }
  64. 'you-view section' { display = 'grid' gap = '.6rem' padding = '.8rem' background = colorSurface border = '1px solid ' + colorBorder borderRadius = '.5rem' }
  65. 'you-view dl' { display = 'grid' gap = '.2rem' margin = '0' }
  66. 'you-view dt' { fontSize = '.85rem' color = colorTextMuted }
  67. 'you-view dd' { margin = '0 0 .4rem' color = colorTextStrong overflowWrap = 'anywhere' }
  68. 'you-view code' { overflowWrap = 'anywhere' wordBreak = 'break-all' }
  69. '#tokenform' { display = 'grid' gap = '.5rem' }
  70. tokenShown { display = 'grid' gap = '.4rem' padding = '.7rem' border = '1px solid ' + colorSuccess borderRadius = '.4rem' }
  71. 'token-shown p' { margin = '0' }
  72. '#newtoken' { color = colorSuccess fontSize = '.95rem' }
  73. '#tokenlist' { listStyle = 'none' margin = '0' padding = '0' display = 'grid' gap = '.4rem' }
  74. '#tokenlist li' { display = 'flex' flexWrap = 'wrap' alignItems = 'center' gap = '.3rem .8rem' padding = '.4rem .6rem' background = colorBackgroundSunken borderRadius = '.4rem' }
  75. '#tokenlist .label' { flex = '1 1 10rem' color = colorTextStrong overflowWrap = 'anywhere' }
  76. // ---- ticket lists (/, filters, /inbox) -----------------------------------------------------
  77. ticketBoard { display = 'grid' gap = '1rem' }
  78. ticketFilters { display = 'grid' gap = '.5rem' }
  79. 'ticket-filters nav' { display = 'flex' flexWrap = 'wrap' gap = '.35rem' }
  80. 'ticket-filters a' { padding = '.2rem .65rem' fontSize = '.85rem' color = colorText border = '1px solid ' + colorBorder borderRadius = '999px' }
  81. 'ticket-filters a.selected' { color = colorAccentText background = colorAccent borderColor = colorAccent }
  82. '.tickets' { listStyle = 'none' margin = '0' padding = '0' display = 'grid' gap = '.5rem' }
  83. '.tickets li' { display = 'grid' gridTemplateColumns = 'minmax(0, 1fr)' gap = '.3rem' padding = '.7rem .8rem' background = colorSurface border = '1px solid ' + colorBorder borderRadius = '.5rem' }
  84. '.tickets li ticket-state' { justifySelf = 'start' }
  85. '.tickets .subject' { color = colorTextStrong fontWeight = '600' overflowWrap = 'anywhere' }
  86. ticketRef { marginRight = '.4rem' color = colorTextMuted fontWeight = '400' }
  87. formerRef { marginLeft = '.2rem' fontSize = '.85rem' color = colorTextMuted }
  88. ticketMeta { display = 'flex' flexWrap = 'wrap' gap = '.2rem .8rem' fontSize = '.85rem' }
  89. '.empty' { margin = '0' padding = '1rem' textAlign = 'center' color = colorTextMuted border = '1px dashed ' + colorBorder borderRadius = '.5rem' }
  90. '.notice' { margin = '0' color = colorSuccess }
  91. // the new-ticket form, folded away until asked for
  92. details { background = colorSurface border = '1px solid ' + colorBorder borderRadius = '.5rem' }
  93. summary { padding = '.6rem .8rem' cursor = 'pointer' fontWeight = '600' color = colorAccent }
  94. 'details form' { display = 'grid' gap = '.7rem' padding = '0 .8rem .8rem' }
  95. // ---- the state badge: one colour per state -------------------------------------------------
  96. ticketState { display = 'inline-block' padding = '.05rem .55rem' fontSize = '.8rem' fontWeight = '600' whiteSpace = 'nowrap' borderRadius = '999px' border = '1px solid currentColor' color = colorTextMuted }
  97. 'ticket-state.open' { color = colorAction }
  98. 'ticket-state.progress' { color = colorWarning }
  99. 'ticket-state.pending' { color = colorTextMuted }
  100. 'ticket-state.review' { color = colorAccent }
  101. 'ticket-state.reopened' { color = colorDanger }
  102. 'ticket-state.done' { color = colorSuccess }
  103. 'ticket-state.canceled' { color = colorTextMuted }
  104. 'ticket-filters a.selected.open,
  105. ticket-filters a.selected.progress,
  106. ticket-filters a.selected.pending,
  107. ticket-filters a.selected.review,
  108. ticket-filters a.selected.reopened,
  109. ticket-filters a.selected.done,
  110. ticket-filters a.selected.canceled' { color = colorAccentText }
  111. // ---- ticket #20: projects, members, assignee, the inbox ------------------------------------------
  112. projectActions { display = 'flex' flexWrap = 'wrap' gap = '.5rem' }
  113. // ticket #21: the apps connected to a project, and the connect page
  114. '.connections' { listStyle = 'none' margin = '0' padding = '0' display = 'grid' gap = '.4rem' }
  115. '.connections li' { display = 'flex' flexWrap = 'wrap' alignItems = 'center' gap = '.2rem .6rem' padding = '.4rem .8rem' background = colorSurface border = '1px solid ' + colorBorder borderRadius = '.5rem' fontSize = '.9rem' }
  116. connectPage { display = 'grid' gap = '1rem' maxWidth = '38rem' }
  117. 'connect-page form' { display = 'grid' gap = '.8rem' }
  118. projectDescription { display = 'block' padding = '.8rem' overflowWrap = 'anywhere' background = colorSurface border = '1px solid ' + colorBorder borderRadius = '.5rem' }
  119. assignee { color = colorTextMuted }
  120. 'assignee::before' { content = '"→ "' }
  121. 'ticket-view .people' { margin = '0' color = colorTextMuted fontSize = '.9rem' }
  122. 'ticket-view .people strong' { color = colorText }
  123. 'project-form,
  124. project-settings' { display = 'grid' gridTemplateColumns = 'minmax(0, 1fr)' gap = '1rem' }
  125. 'project-form form,
  126. project-settings form,
  127. project-settings section' { display = 'grid' gap = '.6rem' }
  128. 'project-settings h1,
  129. project-settings h2' { margin = '0' }
  130. 'project-settings h2' { fontSize = '1.1rem' }
  131. '#members' { listStyle = 'none' margin = '0' padding = '0' display = 'grid' gap = '.4rem' }
  132. '#members li' { display = 'flex' flexWrap = 'wrap' alignItems = 'center' gap = '.4rem .8rem' padding = '.4rem .6rem' background = colorSurface border = '1px solid ' + colorBorder borderRadius = '.4rem' }
  133. '#members strong' { flex = '1 1 8rem' }
  134. inviteShown { display = 'block' padding = '.7rem .8rem' overflowWrap = 'anywhere' background = colorSurface border = '1px solid ' + colorAccent borderRadius = '.5rem' }
  135. 'invite-shown p' { margin = '0 0 .4rem' }
  136. '#projectlist' { listStyle = 'none' margin = '0' padding = '0' display = 'grid' gap = '.3rem' }
  137. '.role' { color = colorTextMuted fontSize = '.85rem' }
  138. '#reviewbox,
  139. #pendingbox' { display = 'grid' gap = '.5rem' }
  140. '#reviewbox h2,
  141. #pendingbox h2' { margin = '0' fontSize = '1.1rem' }
  142. // ---- one ticket ----------------------------------------------------------------------------
  143. ticketView { display = 'grid' gridTemplateColumns = 'minmax(0, 1fr)' gap = '1.2rem' }
  144. 'ticket-view header' { display = 'grid' gap = '.4rem' }
  145. 'ticket-view header p' { margin = '0' }
  146. 'ticket-view header ticket-state' { justifySelf = 'start' }
  147. 'ticket-view .dates' { color = colorTextMuted fontSize = '.85rem' }
  148. ticketSummary { display = 'block' padding = '.8rem' overflowWrap = 'anywhere' background = colorSurface border = '1px solid ' + colorBorder borderRadius = '.5rem' }
  149. 'ticket-view section' { display = 'grid' gap = '.7rem' }
  150. '#events' { listStyle = 'none' margin = '0' padding = '0' display = 'grid' gap = '.5rem' borderLeft = '2px solid ' + colorBorder }
  151. '#events > li' { marginLeft = '.8rem' padding = '.5rem .7rem' background = colorSurface borderRadius = '.4rem' }
  152. '#events > li.state' { background = 'transparent' padding = '.2rem .7rem' }
  153. eventHead { display = 'block' fontSize = '.9rem' }
  154. 'event-head strong' { color = colorTextStrong }
  155. eventText { display = 'block' marginTop = '.3rem' overflowWrap = 'anywhere' }
  156. 'ticket-view form' { display = 'grid' gap = '.5rem' }
  157. // ---- ticket #8: the author's edit form; an edit in the history keeps what was before -------
  158. '#editform' { padding = '.8rem' background = colorSurface border = '1px solid ' + colorAccent borderRadius = '.5rem' }
  159. formButtons { display = 'flex' flexWrap = 'wrap' gap = '.5rem' }
  160. 'event-text.edit' { fontSize = '.9rem' color = colorTextMuted }
  161. 'event-text.edit p' { margin = '0' }
  162. 'event-text.edit s' { color = colorText }
  163. 'event-text.edit details' { marginTop = '.3rem' background = colorBackgroundSunken }
  164. 'event-text.edit summary' { padding = '.3rem .6rem' fontWeight = '400' fontSize = '.85rem' }
  165. 'event-text.edit markdown-text' { padding = '0 .6rem .5rem' color = colorText }
  166. // ---- ticket #6: Markdown in text fields (components/markdown.hl). Line breaks inside a
  167. // paragraph stay visible (the page showed the texts with pre-wrap before) ----------------------
  168. markdownText { display = 'block' }
  169. 'markdown-text > :first-child' { marginTop = '0' }
  170. 'markdown-text > :last-child' { marginBottom = '0' }
  171. 'markdown-text p,
  172. markdown-text li' { whiteSpace = 'pre-wrap' }
  173. 'markdown-text p' { margin = '.5rem 0' }
  174. 'markdown-text h3,
  175. markdown-text h4,
  176. markdown-text h5' { margin = '.9rem 0 .4rem' lineHeight = '1.3' color = colorTextStrong }
  177. 'markdown-text h3' { fontSize = '1.15rem' }
  178. 'markdown-text h4' { fontSize = '1.02rem' }
  179. 'markdown-text h5' { fontSize = '.95rem' }
  180. 'markdown-text ul,
  181. markdown-text ol' { margin = '.5rem 0' paddingLeft = '1.4rem' }
  182. 'markdown-text li + li' { marginTop = '.15rem' }
  183. // inside the history (itself an <ol>) a list would get the nested markers (circles)
  184. 'markdown-text ul' { listStyleType = 'disc' }
  185. 'markdown-text ol' { listStyleType = 'decimal' }
  186. 'markdown-text strong' { color = colorTextStrong }
  187. 'markdown-text a' { textDecoration = 'underline' textUnderlineOffset = '.15em' overflowWrap = 'anywhere' }
  188. 'markdown-text code' { font = '.88em/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace' padding = '.05em .3em' color = colorTextStrong background = colorBackgroundSunken borderRadius = '.25rem' }
  189. 'markdown-text pre' { margin = '.5rem 0' padding = '.6rem .7rem' overflowX = 'auto' background = colorBackgroundSunken border = '1px solid ' + colorBorder borderRadius = '.4rem' }
  190. 'markdown-text pre code' { padding = '0' background = 'transparent' whiteSpace = 'pre' }
  191. '.message' { margin = '0' minHeight = '1.5em' color = colorDanger }
  192. // ---- ticket #12 (mission 024): <md-editor> (shared/md-editor.js, shadow DOM) takes the app's
  193. // tokens through its --md-* custom properties; headings look like the rendered ones (h3/h4/h5 above)
  194. mdEditor { '--md-background' = colorBackgroundSunken '--md-text' = colorText '--md-text-strong' = colorTextStrong '--md-text-muted' = colorTextMuted '--md-border' = colorBorder '--md-accent' = colorAccent '--md-accent-text' = colorAccentText '--md-link' = colorAccent '--md-code-background' = colorSurface '--md-toolbar-background' = colorSurface '--md-danger' = colorDanger '--md-h1-size' = '1.15rem' '--md-h2-size' = '1.02rem' '--md-h3-size' = '.95rem' '--md-min-height' = '2.6rem' color = colorText }
  195. // ---- ticket #4: relations (parent, children, blocked by, blocks) ---------------------------
  196. ticketRelations { display = 'grid' gap = '.8rem' padding = '.8rem' background = colorSurface border = '1px solid ' + colorBorder borderRadius = '.5rem' }
  197. 'ticket-relations h2' { margin = '0 0 .4rem' fontSize = '1rem' }
  198. 'ticket-relations p' { margin = '0' }
  199. '#parent a,
  200. .refs a' { fontWeight = '600' whiteSpace = 'nowrap' }
  201. '.refsubject' { color = colorTextStrong overflowWrap = 'anywhere' }
  202. '#childnote' { margin = '0 0 .4rem' fontSize = '.9rem' color = colorTextMuted }
  203. '#childnote.done' { fontWeight = '600' color = colorSuccess }
  204. '.refs' { listStyle = 'none' margin = '0' padding = '0' display = 'grid' gap = '.35rem' }
  205. '.refs li' { display = 'flex' flexWrap = 'wrap' alignItems = 'baseline' gap = '.2rem .6rem' }
  206. '.refs .unblock' { padding = '.1rem .6rem' fontSize = '.8rem' marginLeft = 'auto' }
  207. '#events > li.link' { background = 'transparent' padding = '.2rem .7rem' }
  208. '@media (min-width: 45rem)' = {
  209. main = { padding = '1.5rem 1rem' }
  210. h1 = { fontSize = '1.6rem' }
  211. '.tickets li' = { gridTemplateColumns = '8.5rem minmax(0, 1fr) auto' alignItems = 'baseline' gap = '1rem' }
  212. '#stateform' = { gridTemplateColumns = '14rem minmax(0, 1fr) auto' alignItems = 'end' }
  213. '#parentform,
  214. #blockerform' = { gridTemplateColumns = 'minmax(0, 1fr) auto' alignItems = 'end' }
  215. 'details form' = { maxWidth = '40rem' }
  216. userBox = { marginLeft = '0' }
  217. }

Branches

Latest commits

  • 752fbb7fdeploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
  • 38bdd5e4deploy.sh: never send .git or .gitignore to Byrodinmre
  • f12fa1bcState of 2026-09-27, before the move to gitoriamre