/* Copyright 2022 Mozilla Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ :root { --outline-width: 2px; --outline-color: #0060df; --outline-around-width: 1px; --outline-around-color: #f0f0f4; --hover-outline-around-color: var(--outline-around-color); --focus-outline: solid var(--outline-width) var(--outline-color); --unfocus-outline: solid var(--outline-width) transparent; --focus-outline-around: solid var(--outline-around-width) var(--outline-around-color); --hover-outline-color: #8f8f9d; --hover-outline: solid var(--outline-width) var(--hover-outline-color); --hover-outline-around: solid var(--outline-around-width) var(--hover-outline-around-color); --freetext-line-height: 1.35; --freetext-padding: 2px; --resizer-bg-color: var(--outline-color); --resizer-size: 6px; --resizer-shift: calc( 0px - (var(--outline-width) + var(--resizer-size)) / 2 - var(--outline-around-width) ); --editorFreeText-editing-cursor: text; /*#if COMPONENTS*/ --editorInk-editing-cursor: pointer; /*#else*/ --editorInk-editing-cursor: url(images/cursor-editorInk.svg) 0 16, pointer; /*#endif*/ --alt-text-opacity: 0.8; --alt-text-add-image: url(images/altText_add.svg); --alt-text-done-image: url(images/altText_done.svg); --alt-text-bg-color: rgba(43, 42, 51, var(--alt-text-opacity)); --alt-text-fg-color: #fbfbfe; --alt-text-border-color: var(--alt-text-bg-color); --alt-text-hover-bg-color: rgba(82, 82, 94, var(--alt-text-opacity)); --alt-text-hover-fg-color: var(--alt-text-fg-color); --alt-text-hover-border-color: var(--alt-text-hover-bg-color); --alt-text-active-bg-color: rgba(91, 91, 102, var(--alt-text-opacity)); --alt-text-active-fg-color: var(--alt-text-fg-color); --alt-text-active-border-color: var(--alt-text-hover-bg-color); --alt-text-focus-outline-color: #0060df; --alt-text-focus-border-color: #f0f0f4; --alt-text-shadow: 0 2px 6px 0 rgba(28, 27, 34, 0.5); } @media (min-resolution: 1.1dppx) { :root { /*#if !COMPONENTS*/ --editorFreeText-editing-cursor: url(images/cursor-editorFreeText.svg) 0 16, text; /*#endif*/ } } @media screen and (forced-colors: active) { :root { --outline-color: CanvasText; --outline-around-color: ButtonFace; --resizer-bg-color: ButtonText; --hover-outline-color: Highlight; --hover-outline-around-color: SelectedItemText; --alt-text-bg-color: Canvas; --alt-text-fg-color: ButtonText; --alt-text-border-color: ButtonText; --alt-text-hover-bg-color: Canvas; --alt-text-hover-fg-color: SelectedItem; --alt-text-hover-border-color: SelectedItem; --alt-text-active-bg-color: ButtonFace; --alt-text-active-fg-color: SelectedItem; --alt-text-active-border-color: ButtonText; --alt-text-focus-outline-color: CanvasText; --alt-text-focus-border-color: ButtonText; --alt-text-shadow: none; --alt-text-opacity: 1; } } [data-editor-rotation="90"] { transform: rotate(90deg); } [data-editor-rotation="180"] { transform: rotate(180deg); } [data-editor-rotation="270"] { transform: rotate(270deg); } .annotationEditorLayer { background: transparent; position: absolute; inset: 0; font-size: calc(100px * var(--scale-factor)); transform-origin: 0 0; cursor: auto; z-index: 4; } .annotationEditorLayer.waiting { content: ""; cursor: wait; position: absolute; inset: 0; width: 100%; height: 100%; } .annotationEditorLayer.freetextEditing { cursor: var(--editorFreeText-editing-cursor); } .annotationEditorLayer.inkEditing { cursor: var(--editorInk-editing-cursor); } .annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) { position: absolute; background: transparent; z-index: 1; transform-origin: 0 0; cursor: auto; max-width: 100%; max-height: 100%; border: var(--unfocus-outline); &.draggable.selectedEditor { cursor: move; } &.selectedEditor { border: var(--focus-outline); outline: var(--focus-outline-around); &::before { /* This is a workaround for the lack of support for stripes(...) (see https://drafts.csswg.org/css-images-4/#stripes). The outline should be composed of 1px white, 2px blue and 1px white. This could be achieved in different ways: - using a linear-gradient; - using a box-shadow; - using an outline on the selected element and an outline+border on the ::before pseudo-element. All these options lead to incorrect rendering likely due to rounding issues. That said it doesn't mean that the current is ideal, but it's the best we could come up with for the moment. One drawback of this approach is that we use a border on the selected element which means that we must take care of it when positioning the div in js (see AnnotationEditor._borderLineWidth in editor.js). */ content: ""; position: absolute; inset: 0; border: var(--focus-outline-around); pointer-events: none; } } &:hover:not(.selectedEditor) { border: var(--hover-outline); outline: var(--hover-outline-around); &::before { content: ""; position: absolute; inset: 0; border: var(--focus-outline-around); } } } .annotationEditorLayer .freeTextEditor { padding: calc(var(--freetext-padding) * var(--scale-factor)); width: auto; height: auto; touch-action: none; } .annotationEditorLayer .freeTextEditor .internal { background: transparent; border: none; inset: 0; overflow: visible; white-space: nowrap; font: 10px sans-serif; line-height: var(--freetext-line-height); user-select: none; } .annotationEditorLayer .freeTextEditor .overlay { position: absolute; display: none; background: transparent; inset: 0; width: 100%; height: 100%; } .annotationEditorLayer .freeTextEditor .overlay.enabled { display: block; } .annotationEditorLayer .freeTextEditor .internal:empty::before { content: attr(default-content); color: gray; } .annotationEditorLayer .freeTextEditor .internal:focus { outline: none; user-select: auto; } .annotationEditorLayer .inkEditor { width: 100%; height: 100%; } .annotationEditorLayer .inkEditor.editing { cursor: inherit; } .annotationEditorLayer .inkEditor .inkEditorCanvas { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; } .annotationEditorLayer .stampEditor { width: auto; height: auto; } .annotationEditorLayer .stampEditor canvas { width: 100%; height: 100%; } .annotationEditorLayer { :is(.freeTextEditor, .inkEditor, .stampEditor) { & > .resizers { position: absolute; inset: 0; &.hidden { display: none; } & > .resizer { width: var(--resizer-size); height: var(--resizer-size); background: content-box var(--resizer-bg-color); border: var(--focus-outline-around); border-radius: 2px; position: absolute; &.topLeft { top: var(--resizer-shift); left: var(--resizer-shift); } &.topMiddle { top: var(--resizer-shift); left: calc(50% + var(--resizer-shift)); } &.topRight { top: var(--resizer-shift); right: var(--resizer-shift); } &.middleRight { top: calc(50% + var(--resizer-shift)); right: var(--resizer-shift); } &.bottomRight { bottom: var(--resizer-shift); right: var(--resizer-shift); } &.bottomMiddle { bottom: var(--resizer-shift); left: calc(50% + var(--resizer-shift)); } &.bottomLeft { bottom: var(--resizer-shift); left: var(--resizer-shift); } &.middleLeft { top: calc(50% + var(--resizer-shift)); left: var(--resizer-shift); } } } } &[data-main-rotation="0"] :is([data-editor-rotation="0"], [data-editor-rotation="180"]), &[data-main-rotation="90"] :is([data-editor-rotation="270"], [data-editor-rotation="90"]), &[data-main-rotation="180"] :is([data-editor-rotation="180"], [data-editor-rotation="0"]), &[data-main-rotation="270"] :is([data-editor-rotation="90"], [data-editor-rotation="270"]) { & > .resizers > .resizer { &.topLeft, &.bottomRight { cursor: nwse-resize; } &.topMiddle, &.bottomMiddle { cursor: ns-resize; } &.topRight, &.bottomLeft { cursor: nesw-resize; } &.middleRight, &.middleLeft { cursor: ew-resize; } } } &[data-main-rotation="0"] :is([data-editor-rotation="90"], [data-editor-rotation="270"]), &[data-main-rotation="90"] :is([data-editor-rotation="0"], [data-editor-rotation="180"]), &[data-main-rotation="180"] :is([data-editor-rotation="270"], [data-editor-rotation="90"]), &[data-main-rotation="270"] :is([data-editor-rotation="180"], [data-editor-rotation="0"]) { & > .resizers > .resizer { &.topLeft, &.bottomRight { cursor: nesw-resize; } &.topMiddle, &.bottomMiddle { cursor: ew-resize; } &.topRight, &.bottomLeft { cursor: nwse-resize; } &.middleRight, &.middleLeft { cursor: ns-resize; } } } & :is( [data-main-rotation="0"] [data-editor-rotation="90"], [data-main-rotation="90"] [data-editor-rotation="0"], [data-main-rotation="180"] [data-editor-rotation="270"], [data-main-rotation="270"] [data-editor-rotation="180"] ) { & .altText { rotate: 270deg; &:dir(ltr) { inset-inline-start: calc(100% - 8px); &.small { inset-inline-start: calc(100% + 8px); inset-block-start: 100%; } } &:dir(rtl) { inset-block-end: calc(100% - 8px); &.small { inset-inline-start: -8px; inset-block-start: 0; } } } } & :is( [data-main-rotation="0"] [data-editor-rotation="180"], [data-main-rotation="90"] [data-editor-rotation="90"], [data-main-rotation="180"] [data-editor-rotation="0"], [data-main-rotation="270"] [data-editor-rotation="270"] ) { & .altText { rotate: 180deg; inset-block-end: calc(100% - 8px); inset-inline-start: calc(100% - 8px); &.small { inset-inline-start: 100%; inset-block-start: -8px; } } } & :is( [data-main-rotation="0"] [data-editor-rotation="270"], [data-main-rotation="90"] [data-editor-rotation="180"], [data-main-rotation="180"] [data-editor-rotation="90"], [data-main-rotation="270"] [data-editor-rotation="0"] ) { & .altText { rotate: 90deg; &:dir(ltr) { inset-block-end: calc(100% - 8px); &.small { inset-inline-start: -8px; inset-block-start: 0; } } &:dir(rtl) { inset-inline-start: calc(100% - 8px); &.small { inset-inline-start: calc(100% + 8px); inset-block-start: 100%; } } } } } .altText { display: flex; align-items: center; justify-content: center; padding-inline: 4px; width: auto; height: 24px; min-width: 88px; z-index: 1; pointer-events: all; color: var(--alt-text-fg-color); font: menu; font-size: 12px; border-radius: 4px; border: 1px solid var(--alt-text-border-color); background-color: var(--alt-text-bg-color); box-shadow: var(--alt-text-shadow); position: absolute; inset-block-end: 8px; inset-inline-start: 8px; &:disabled { pointer-events: none; } &:dir(ltr) { transform-origin: 0 100%; } &:dir(rtl) { transform-origin: 100% 100%; } &.small { &:dir(ltr) { transform-origin: 0 0; } &:dir(rtl) { transform-origin: 100% 0; } inset-block-end: unset; inset-inline-start: 0; inset-block-start: calc(100% + 8px); } &:hover { background-color: var(--alt-text-hover-bg-color); border-color: var(--alt-text-hover-border-color); color: var(--alt-text-hover-fg-color); cursor: pointer; &::before { background-color: var(--alt-text-hover-fg-color); } } &:active { background-color: var(--alt-text-active-bg-color); border-color: var(--alt-text-active-border-color); color: var(--alt-text-active-fg-color); &::before { background-color: var(--alt-text-active-fg-color); } } &:focus-visible { outline: 2px solid var(--alt-text-focus-outline-color); border-color: var(--alt-text-focus-border-color); } &::before { content: ""; mask-image: var(--alt-text-add-image); mask-repeat: no-repeat; mask-position: center; display: inline-block; width: 12px; height: 13px; background-color: var(--alt-text-fg-color); margin-inline-end: 4px; } &.done::before { mask-image: var(--alt-text-done-image); } & .tooltip { display: none; &.show { --alt-text-tooltip-bg: #f0f0f4; --alt-text-tooltip-fg: #15141a; --alt-text-tooltip-border: #8f8f9d; --alt-text-tooltip-shadow: 0px 2px 6px 0px rgba(58, 57, 68, 0.2); @media (prefers-color-scheme: dark) { --alt-text-tooltip-bg: #1c1b22; --alt-text-tooltip-fg: #fbfbfe; --alt-text-tooltip-shadow: 0px 2px 6px 0px #15141a; } @media screen and (forced-colors: active) { --alt-text-tooltip-bg: Canvas; --alt-text-tooltip-fg: CanvasText; --alt-text-tooltip-border: CanvasText; --alt-text-tooltip-shadow: none; } display: inline-flex; flex-direction: column; align-items: center; justify-content: center; position: absolute; top: calc(100% + 2px); inset-inline-start: 0; padding-block: 2px 3px; padding-inline: 3px; max-width: 300px; width: max-content; height: auto; font-size: 12px; border: 0.5px solid var(--alt-text-tooltip-border); background: var(--alt-text-tooltip-bg); box-shadow: var(--alt-text-tooltip-shadow); color: var(--alt-text-tooltip-fg); pointer-events: none; } } } #altTextDialog { --dialog-bg-color: white; --dialog-border-color: white; --dialog-shadow: 0 2px 14px 0 rgba(58, 57, 68, 0.2); --text-primary-color: #15141a; --text-secondary-color: #5b5b66; --hover-filter: brightness(0.9); --focus-ring-color: #0060df; --focus-ring-outline: 2px solid var(--focus-ring-color); --textarea-border-color: #8f8f9d; --textarea-bg-color: white; --textarea-fg-color: var(--text-secondary-color); --radio-bg-color: #f0f0f4; --radio-checked-bg-color: #fbfbfe; --radio-border-color: #8f8f9d; --radio-checked-border-color: #0060df; --button-cancel-bg-color: #f0f0f4; --button-cancel-fg-color: var(--text-primary-color); --button-cancel-border-color: var(--button-cancel-bg-color); --button-cancel-hover-bg-color: var(--button-cancel-bg-color); --button-cancel-hover-fg-color: var(--button-cancel-fg-color); --button-cancel-hover-border-color: var(--button-cancel-hover-bg-color); --button-save-bg-color: #0060df; --button-save-fg-color: #fbfbfe; --button-save-hover-bg-color: var(--button-save-bg-color); --button-save-hover-fg-color: var(--button-save-fg-color); --button-save-hover-border-color: var(--button-save-hover-bg-color); --button-save-disabled-bg-color: var(--button-save-bg-color); --button-save-disabled-fg-color: var(--button-save-fg-color); --button-save-disabled-opacity: 0.4; @media (prefers-color-scheme: dark) { --dialog-bg-color: #1c1b22; --dialog-border-color: #1c1b22; --dialog-shadow: 0 2px 14px 0 #15141a; --text-primary-color: #fbfbfe; --text-secondary-color: #cfcfd8; --focus-ring-color: #00ddff; --hover-filter: brightness(1.4); --textarea-bg-color: #42414d; --radio-bg-color: #2b2a33; --radio-checked-bg-color: #15141a; --radio-checked-border-color: #00ddff; --button-cancel-bg-color: #2b2a33; --button-save-bg-color: #00ddff; --button-save-fg-color: #15141a; } @media screen and (forced-colors: active) { --dialog-bg-color: Canvas; --dialog-border-color: CanvasText; --dialog-shadow: none; --text-primary-color: CanvasText; --text-secondary-color: CanvasText; --hover-filter: none; --focus-ring-color: ButtonBorder; --textarea-border-color: ButtonBorder; --textarea-bg-color: Field; --textarea-fg-color: ButtonText; --radio-bg-color: ButtonFace; --radio-checked-bg-color: ButtonFace; --radio-border-color: ButtonText; --radio-checked-border-color: ButtonText; --button-cancel-bg-color: ButtonFace; --button-cancel-fg-color: ButtonText; --button-cancel-border-color: ButtonText; --button-cancel-hover-bg-color: AccentColor; --button-cancel-hover-fg-color: AccentColorText; --button-save-bg-color: ButtonText; --button-save-fg-color: ButtonFace; --button-save-hover-bg-color: AccentColor; --button-save-hover-fg-color: AccentColorText; --button-save-disabled-bg-color: GrayText; --button-save-disabled-fg-color: Canvas; --button-save-disabled-opacity: 1; } font: message-box; font-size: 13px; font-weight: 400; line-height: 150%; border-radius: 4px; padding: 12px 16px; border: 1px solid var(--dialog-border-color); background: var(--dialog-bg-color); color: var(--text-primary-color); box-shadow: var(--dialog-shadow); &::backdrop { /* This is needed to avoid to darken the image the user want to describe. */ mask: url(#alttext-manager-mask); } &.positioned { margin: 0; } & #altTextContainer { width: 300px; height: fit-content; display: inline-flex; flex-direction: column; align-items: flex-start; gap: 16px; & *:focus-visible { outline: var(--focus-ring-outline); outline-offset: 2px; } & .radio { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; & .radioButton { display: flex; gap: 8px; align-self: stretch; align-items: center; & input { appearance: none; box-sizing: border-box; width: 16px; height: 16px; border-radius: 50%; background-color: var(--radio-bg-color); border: 1px solid var(--radio-border-color); &:hover { filter: var(--hover-filter); } &:checked { background-color: var(--radio-checked-bg-color); border: 4px solid var(--radio-checked-border-color); } } } & .radioLabel { display: flex; padding-inline-start: 24px; align-items: flex-start; gap: 10px; align-self: stretch; & span { flex: 1 0 0; font-size: 11px; color: var(--text-secondary-color); } } } & #overallDescription { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; align-self: stretch; & span { align-self: stretch; } & .title { font-size: 13px; font-style: normal; font-weight: 590; } } & #addDescription { display: flex; flex-direction: column; align-items: stretch; gap: 8px; & .descriptionArea { flex: 1; padding-inline: 24px 10px; textarea { font: inherit; width: 100%; min-height: 75px; padding: 8px; resize: none; margin: 0; box-sizing: border-box; border-radius: 4px; border: 1px solid var(--textarea-border-color); background: var(--textarea-bg-color); color: var(--textarea-fg-color); &:focus { outline-offset: 0; border-color: transparent; } &:disabled { pointer-events: none; opacity: 0.4; } } } } & #buttons { display: flex; justify-content: flex-end; align-items: flex-start; gap: 8px; align-self: stretch; button { border-radius: 4px; border: 1px solid; font: menu; font-weight: 600; padding: 4px 16px; width: auto; height: 32px; &:hover { cursor: pointer; filter: var(--hover-filter); } &#altTextCancel { color: var(--button-cancel-fg-color); background-color: var(--button-cancel-bg-color); border-color: var(--button-cancel-border-color); &:hover { color: var(--button-cancel-hover-fg-color); background-color: var(--button-cancel-hover-bg-color); border-color: var(--button-cancel-hover-border-color); } } &#altTextSave { color: var(--button-save-hover-fg-color); background-color: var(--button-save-hover-bg-color); border-color: var(--button-save-hover-border-color); opacity: 1; &:hover { color: var(--button-save-hover-fg-color); background-color: var(--button-save-hover-bg-color); border-color: var(--button-save-hover-border-color); } &:disabled { color: var(--button-save-disabled-fg-color); background-color: var(--button-save-disabled-bg-color); opacity: var(--button-save-disabled-opacity); pointer-events: none; } } } } } }