/* ==========================================================================
   PD-66 — Tela de Agendamento musical (views/playlist/musicalSchedule.html)

   Arquivo dedicado, carregado DEPOIS de main.css no index.html.
   Todas as classes desta tela (.heading-ms, .box-dropdown-unity, .periods-info*,
   .shift*, a.schedule-element) são exclusivas deste template — override aqui não
   afeta a tela de Playlists, que compartilha PlaylistController.js e main.css.
   ========================================================================== */

:root {
  /* sentinela: confirma no navegador QUAL versao deste arquivo esta carregada.
     No console:  getComputedStyle(document.documentElement)
                    .getPropertyValue('--ms-css-build')
     Se vier vazio, a pagina esta usando um CSS antigo (cache) ou outro servidor. */
  --ms-css-build: "2026-08-21-1";
  /* Gradiente rosa do produto — repetido literalmente em 4 pontos do main.css */
  --ms-pink-gradient: linear-gradient(96deg, #FC3A7D 28.62%, #FF424D 116.71%);
  --ms-pink: var(--pink-listenx, #fc3a7d);

  --ms-graphite: #3D3D3D;
  --ms-graphite-hover: #262626;

  --ms-txt-title: #4D4D4D;
  --ms-txt-600: var(--txt-600, #666);
  --ms-txt-500: var(--txt-500, #808080);

  --ms-border: #CFCFCF;
  --ms-row-bg: var(--row-bg, #F7F7F7);
  --ms-radius: var(--radius-6, .375rem);

  --ms-disabled-bg: #C9C9C9;
}

.ms-page-wrapper {
  box-shadow: none !important;
}

/* Modo de visualização por token (state musicalScheduleView). A faixa era um
   bloco `position:fixed` solto no fim do template, sem fundo nem z-index — com
   o header novo no topo da página os dois se sobrepunham. */
.ms-admin-view-bar {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1030;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 50px;
  background: #FFF;
  border-bottom: 1px solid #E9E9E9;
}

.ms-admin-view-bar h2 {
  margin: 0;
  color: var(--ms-txt-600);
  font-family: 'Inter';
  font-size: 1rem;
  font-weight: 600;
}

.ms-page-wrapper--admin-view {
  padding-top: 50px;
}

/* --------------------------------------------------------------------------
   1. Header — título à esquerda, Unidade + ações à direita
   -------------------------------------------------------------------------- */

.ms-header {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  gap: 1.5rem;
  flex-wrap: wrap;
  /* sobrepõe .header-info-musical-schedule { margin-bottom: 3.25rem } */
  margin-bottom: 1.5rem;
}

/* .heading-ms nasce centralizado em coluna (main.css:2697) — aqui é à esquerda */
.ms-header .heading-ms {
  align-items: flex-start;
  justify-content: center;
  gap: 0.125rem;
  min-width: 0;
}

.ms-header .heading-ms h2 {
  margin: 0;
  color: var(--ms-txt-title);
  text-align: left;
  font-size: 1.375rem;
  font-weight: 500;
  letter-spacing: -0.0275rem;
}

.ms-header .heading-ms h3 {
  margin: 0;
  color: var(--ms-txt-500);
  text-align: left;
  font-size: 0.8125rem;
  font-weight: 500;
}

.ms-header-actions {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   2. Seletor de Unidade — chip "Unidade" + dropdown
   Regra de exibição inalterada: ng-show setPrograming == 'administrator_by_unit'
   -------------------------------------------------------------------------- */

.ms-header .box-dropdown-unity {
  height: 2.5rem;
  min-width: 20rem;
  max-width: 26rem;
  padding: 0;
  overflow: visible;
  border: 1px solid var(--ms-border);
  border-radius: var(--ms-radius);
  justify-content: flex-start;
}

.ms-header .box-dropdown-unity .text-span-config {
  height: 100%;
  padding: 0 0.875rem;
  background: var(--ms-row-bg);
  border-right: 1px solid var(--ms-border);
  border-top-left-radius: var(--ms-radius);
  border-bottom-left-radius: var(--ms-radius);
  color: var(--ms-txt-500);
  font-size: 0.8125rem;
  font-weight: 500;
  white-space: nowrap;
  flex: 0 0 auto;
}

.ms-header .box-dropdown-unity-select {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  padding: 0 1rem;
  font-size: 0.875rem;
}

/* faz o gatilho ocupar a altura toda da caixa para o dropdown poder
   ancorar em top:100% em vez do top:42px fixo do main.css */
.ms-header .box-dropdown-unity-select .custom-select-search,
.ms-header .box-dropdown-unity-select .custom-select-search__selected-value {
  height: 100%;
  display: flex;
  align-items: center;
}

.ms-header .box-dropdown-unity-select .custom-select-search__selected-value {
  justify-content: space-between;
  gap: 0.5rem;
}

.ms-header .box-dropdown-unity-select .custom-select-search__selected-value>span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ms-txt-600);
}

.ms-header .box-dropdown-unity-select .custom-select-search__dropdown {
  top: 100%;
  left: -1rem;
  width: calc(100% + 2rem);
  border-radius: 0 0 var(--ms-radius) var(--ms-radius);
}

/* --------------------------------------------------------------------------
   3. Botões de ação do header
   -------------------------------------------------------------------------- */

.ms-btn {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 2.5rem;
  padding: 0 1.125rem;
  border: 0;
  border-radius: var(--ms-radius);
  font-family: 'Inter';
  font-size: 0.875rem;
  font-weight: 600;
  line-height: normal;
  letter-spacing: -0.00875rem;
  white-space: nowrap;
  text-decoration: none !important;
  transition: background-color .15s ease, color .15s ease;
}

.ms-btn svg {
  flex: 0 0 auto;
}

/* "Adicionar playlist" — secundário grafite */
.ms-btn-add {
  background: var(--ms-graphite);
  color: #FFF;
}

.ms-btn-add:hover,
.ms-btn-add:focus {
  background: var(--ms-graphite-hover);
  color: #FFF;
}

/* "Agendar e publicar" — primário rosa. A classe .btnSave tem de continuar no
   elemento: PlaylistController.js:943/951 faz $(".btnSave").tooltip(...) */
.ms-btn-publish {
  background: var(--ms-pink-gradient);
  color: #FFF;
}

.ms-btn-publish:hover,
.ms-btn-publish:focus {
  background: #FFF;
  border: 1px solid var(--ms-pink);
  color: var(--ms-pink) !important;
}

/* main.css:11010 (.btn.disabled) só define background-color, que não apaga o
   gradiente; aqui o shorthand zera o background-image de fato */
.ms-btn-publish.disabled,
.ms-btn-publish:disabled {
  background: var(--ms-disabled-bg);
  border: 0;
  color: #FFF !important;
}

/* "Voltar" — terciário, só aparece quando $root.redirectHome */
.ms-btn-back {
  background: #FFF;
  border: 1px solid var(--ms-border);
  color: var(--ms-txt-600);
}

.ms-btn-back:hover,
.ms-btn-back:focus {
  background: var(--ms-row-bg);
  color: var(--ms-txt-600);
}

/* --------------------------------------------------------------------------
   4. Faixa "Tocando agora" / "Próxima playlist"
   -------------------------------------------------------------------------- */

.ms-now-strip {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

/* `flex-start` e nao `center`: com as thumbs ancoradas no topo, as duas ficam
   exatamente na mesma linha (a distancia de cada uma ao topo do seu card e o
   proprio padding de 1rem), independentemente de um card ter conteudo mais alto
   que o outro. Com `center`, qualquer diferenca de altura entre os dois cards
   desalinhava as thumbs pela metade da diferenca.
   O conteudo de texto continua centralizado verticalmente - ver o
   `align-self: stretch` em `.ms-now-card__info`, que preserva o
   `justify-content: center` que ja existia la dentro. */
.ms-now-card {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 1rem;
  min-width: 0;
  padding: 1rem;
  background: #FFF;
  border-radius: 0.75rem;
  box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.05);
}

/* proporção do mockup: ~2/3 para "Tocando agora", ~1/3 para "Próxima playlist" */
.ms-now-card--current {
  flex: 2 1 0;
}

/* Sem "Próxima playlist" (o `ng-if` do card seguinte e falso), o card atual
   ocupa a faixa inteira. `:only-child` conta apenas ELEMENTOS, e o `ng-if` do
   Angular deixa so um comentario no lugar do card removido — por isso funciona.
   O `flex-grow: 2` acima ja preencheria, mas explicito aqui porque e uma regra
   de layout pedida, nao um efeito colateral de estar sozinho no flex. */
.ms-now-card--current:only-child {
  flex: 1 1 100%;
}

.ms-now-card--next {
  flex: 1 1 0;
}

/* --- thumbnail + badge de energia --- */

/* 86x87 no print (a 60%) => 145px. Os DOIS cards usam o mesmo tamanho: no print
   a thumb da "Próxima playlist" tem exatamente a mesma altura da outra. */
.ms-now-card__thumb {
  position: relative;
  /* nao encolhe nem cresce: os dois cards usam exatamente o mesmo quadrado,
     mesmo quando o card da direita fica estreito */
  flex: 0 0 auto;
  align-self: flex-start;
  width: var(--ms-card-media-h);
  height: var(--ms-card-media-h);
  border-radius: 0.625rem;
  overflow: hidden;
  background: var(--ms-row-bg);
}

.ms-now-card__thumb img,
.ms-now-card__thumb-empty {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ms-now-card__thumb-empty {
  background: linear-gradient(135deg, #EDEDED 0%, #DCDCDC 100%);
}

.ms-energy-badge {
  position: absolute;
  top: 0.375rem;
  left: 0.375rem;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  max-width: calc(100% - 0.75rem);
  padding: 0.125rem 0.4375rem 0.125rem 0.375rem;
  border-radius: 62.4375rem;
  background: rgba(0, 0, 0, 0.62);
  color: #FFF;
  font-family: 'Inter';
  font-size: 0.5625rem;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ms-energy-badge i {
  flex: 0 0 auto;
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: currentColor;
}

/* a cor do ponto é o único sinal cromático do nível — o rótulo já diz o resto */
.ms-energy-badge--easy i {
  background: #5BC8C8;
}

.ms-energy-badge--medium i {
  background: #F79433;
}

.ms-energy-badge--fast i {
  background: var(--ms-pink);
}

/* --- coluna de texto --- */

.ms-now-card__info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 0.375rem;
  min-width: 0;
  flex: 1 1 auto;
  /* o card agora alinha pelo topo (ver .ms-now-card); esticar aqui devolve ao
     `justify-content: center` acima a altura de que ele precisa para continuar
     centralizando o texto */
  align-self: stretch;
}

.ms-now-pill {
  display: inline-flex;
  align-items: center;
  padding: 0.1875rem 0.625rem;
  border-radius: 62.4375rem;
  font-family: 'Inter';
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.00688rem;
  white-space: nowrap;
}

/* Os três pills usam o mesmo rosa. O "Programado agora" era cinza até 19/08 —
   o Anderson pediu que ficasse igual ao "Próxima playlist": a diferença entre
   "tocando" e "programado" fica no TEXTO, não na cor. */
.ms-now-pill--current,
.ms-now-pill--next,
.ms-now-pill--scheduled {
  background: #FFE9F1;
  color: var(--ms-pink);
}

.ms-now-card__name {
  margin: 0;
  color: var(--ms-txt-title);
  font-family: 'Inter';
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.35;
  letter-spacing: -0.01063rem;
  overflow-wrap: anywhere;
}

.ms-now-card--next .ms-now-card__name {
  font-size: 0.9375rem;
  /* o mockup quebra o nome em até 3 linhas neste card */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.ms-now-card__name--unknown {
  color: var(--ms-txt-500);
  font-weight: 500;
  font-style: italic;
}

.ms-now-card__meta {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 1.25rem;
  color: var(--ms-txt-500);
  font-family: 'Inter';
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.0075rem;
}

.ms-now-card__meta > span {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
}

.ms-now-card__meta svg {
  flex: 0 0 auto;
  opacity: 0.85;
}

/* --------------------------------------------------------------------------
   5. Waveform decorativa
   O portal não recebe o stream da filial — isto NÃO reflete o áudio real.
   O nível de energia da playlist define só o ritmo da animação.
   -------------------------------------------------------------------------- */

/* Medidas amostradas do NovaTela.png (a 60%, fator 1,6667):
     área ....... 173 x 101 px no print  ->  288 x 168 px reais
     barras ..... 40, largura 2px -> 3,3px, passo 4,33px -> 7,2px
   O perfil de alturas dos 40 spans no template é o do print, barra a barra. */
/* Knobs da onda - ajuste AQUI, nao nas regras abaixo. As alturas dos 40 spans
   no template sao PERCENTUAIS, entao mexer na altura escala a onda inteira.

   `--ms-card-media-h` e a altura COMPARTILHADA pela thumb e pela onda. Elas
   precisam ser iguais: o card alinha pelo topo (`align-items: flex-start`, para
   as duas thumbs cairem na mesma linha), entao qualquer diferenca entre as duas
   vira vao branco embaixo da mais baixa. Com a onda em 12.5rem contra 9rem da
   thumb sobravam 3.5rem de branco. Amarrando as duas na mesma variavel o vao
   deixa de ser possivel, e um ajuste futuro numa delas nao reintroduz o bug.
   No mockup elas tambem tem a mesma altura (thumb 90px x onda 94px no print). */
:root {
  --ms-card-media-h: 10rem;
  --ms-wave-h: var(--ms-card-media-h);
  --ms-wave-bar-w: 0.3125rem;
  --ms-wave-gap: 0.25rem;
  /* opacidade das barras da direita; a da esquerda sai do fade abaixo */
  --ms-wave-opacity: 0.8;
  /* onde o fade da esquerda termina: 0% = sem fade, 100% = some quase tudo */
  --ms-wave-fade: 55%;
}

.ms-waveform {
  display: flex;
  /* 40 barras: 40 * bar-w + 39 * gap */
  flex: 0 1 calc(var(--ms-wave-bar-w) * 40 + var(--ms-wave-gap) * 39);
  align-items: center;
  justify-content: center;
  gap: var(--ms-wave-gap);
  min-width: 0;
  height: var(--ms-wave-h);
  /* o card passou a alinhar pelo topo; a onda segue centralizada */
  align-self: center;
  overflow: hidden;
  /* No mockup a onda nao tem opacidade uniforme: nasce quase invisivel na
     esquerda e ganha corpo para a direita. Feito com mascara no CONTAINER e nao
     com opacity barra a barra, porque assim o degrade e continuo e nao briga
     com a animacao de cada barra. */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 var(--ms-wave-fade));
  mask-image: linear-gradient(to right, transparent 0%, #000 var(--ms-wave-fade));
}

.ms-waveform > span {
  flex: 0 0 auto;
  width: var(--ms-wave-bar-w);
  border-radius: 62.4375rem;
  background: var(--ms-pink);
  opacity: var(--ms-wave-opacity);
  transform-origin: center;
  animation-name: ms-waveform-pulse;
  animation-duration: 1.1s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-delay: calc(var(--i, 0) * 45ms);
}

/* So a ALTURA pulsa. A opacidade saiu daqui: quem cuida dela agora e o fade da
   mascara, e animar as duas coisas fazia a ponta esquerda piscar.
   Para deixar 100% estatico, basta remover o bloco `animation-*` acima. */
@keyframes ms-waveform-pulse {
  from {
    transform: scaleY(0.9);
  }

  to {
    transform: scaleY(1.1);
  }
}

/* ritmo por nível de energia da playlist */
.ms-waveform--easy > span {
  animation-duration: 1.9s;
}

.ms-waveform--medium > span {
  animation-duration: 1.25s;
}

.ms-waveform--fast > span {
  animation-duration: 0.75s;
}

/* Player offline: a onda só PARA de pulsar. Cor, opacidade e o degradê da
   máscara continuam os mesmos do estado tocando — pedido do Anderson em 19/08
   (antes ela virava cinza com opacidade 0.3). O que informa "não está tocando"
   é o texto do pill e a onda parada, não uma cor apagada. */
.ms-waveform--paused > span {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .ms-waveform > span {
    animation: none;
  }
}

/* --------------------------------------------------------------------------
   6. Grade semanal — períodos, régua de horas e blocos agendados

   ⚠️ NADA aqui mexe na GEOMETRIA da grade (decisão fechada na PD-66):
   as 78 regras px de `assets/css/fullcalendar.css` (.hour-start-*, .hour-end-*,
   .week-day-*), o `.shift{height:238px}`, o `.shift span{height:2.20rem}` e o
   `.periods-musical-schedule{padding:1rem 0}` continuam intactos. Onde o visual
   antigo dependia de uma caixa (a cápsula branca da régua), a caixa foi mantida
   e só as cores foram zeradas — trocar `border: 5px solid #F7F7F7` por
   `border-color: transparent` preserva as métricas exatas.
   -------------------------------------------------------------------------- */

:root {
  /* madrugada 00-05 */
  --ms-dawn-bg: #E8F0FA;
  --ms-dawn-fg: #7B9BC4;
  --ms-dawn-icon: #9DBEE3;
  /* manhã 06-11 */
  --ms-morning-bg: #FDF3DC;
  --ms-morning-fg: #C09338;
  --ms-morning-icon: #F2C14E;
  /* tarde 12-17 */
  --ms-afternoon-bg: #FCEADD;
  --ms-afternoon-fg: #CB7440;
  --ms-afternoon-icon: #F79A5B;
  /* noite 18-23 */
  --ms-night-bg: #ECEAFA;
  --ms-night-fg: #7A70BD;
  --ms-night-icon: #A79AE5;

  /* bloco de playlist agendada — cor amostrada do NovaTela.png */
  --ms-block-bg: #FFF5F8;
  --ms-block-bg-hover: #FCEAF1;
  /* respiro entre blocos vizinhos — desenhado como borda BRANCA de cada bloco,
     então o vão real entre dois blocos colados é o dobro deste valor.
     Borda (e não margin) porque o bloco é absoluto e mexer em margin brigaria
     com o top/bottom !important das classes .hour-start-* / .hour-end-*. */
  --ms-block-gap: 4px;
  --ms-block-border: #FFF;
}

/* --- card único: o mockup tem UMA superfície branca, não duas caixas --- */

.delimiter-board-musical-schedule {
  background: #FFF;
  border-radius: 0.75rem;
  box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.05);
}

.delimiter-board-musical-schedule .periods-info,
.delimiter-board-musical-schedule .table-musical-schedule {
  background: transparent;
  box-shadow: none;
}

/* --- coluna lateral de períodos --- */

.periods-info-list svg {
  width: 2.25rem;
  height: 2.25rem;
  margin-bottom: 0.5rem;
}

.periods-info-list span {
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: -0.00875rem;
  color: var(--ms-txt-600);
}

/* os SVGs vinham com fill="#E6E6E6" fixo no template; agora é currentColor */
.periods-info-list.madrugada {
  color: var(--ms-dawn-icon);
}

.periods-info-list.manha {
  color: var(--ms-morning-icon);
}

.periods-info-list.tarde {
  color: var(--ms-afternoon-icon);
}

.periods-info-list.noite {
  color: var(--ms-night-icon);
}

/* --- régua de horas 00-23 --- */

/* a cápsula branca com anel cinza some. A borda de 5px é REMOVIDA (e não só
   deixada transparente) porque a geometria da seção 8 posiciona a régua e os
   blocos na mesma origem — os 5px de borda empurravam a régua para baixo e
   estreitavam as faixas de hora. */
.periods-musical-schedule {
  background: transparent;
  border: 0;
  box-shadow: none;
  align-items: stretch;
}

.periods-musical-schedule .shift {
  border-radius: 0.375rem;
  align-items: stretch;
}

.periods-musical-schedule .shift span {
  color: inherit;
  font-weight: 500;
}

.periods-musical-schedule .early-morning-shift {
  background: var(--ms-dawn-bg);
  color: var(--ms-dawn-fg);
}

.periods-musical-schedule .morning-shift {
  background: var(--ms-morning-bg);
  color: var(--ms-morning-fg);
}

.periods-musical-schedule .afternoon-shift {
  background: var(--ms-afternoon-bg);
  color: var(--ms-afternoon-fg);
}

.periods-musical-schedule .night-shift {
  background: var(--ms-night-bg);
  color: var(--ms-night-fg);
}

/* as barrinhas cinza separadoras dão lugar ao gap entre os blocos coloridos */
.periods-musical-schedule .shift:nth-child(-n+3)::after {
  content: none;
}

/* --- blocos de playlist agendada --- */

/* Cada playlist é um retângulo rosa próprio, com cantos arredondados. A borda
   BRANCA (`--ms-block-gap`) é o que separa um bloco do vizinho de baixo e do
   da coluna ao lado — sem ela, blocos colados (ex.: Sáb 00:00-08:00 seguido de
   08:00-10:00, ou a coluna de Sexta encostada na de Sábado) viram uma mancha
   rosa contínua. Como o fundo da grade é branco, a borda não lê como traço e
   sim como respiro. Fica DENTRO da caixa do bloco, então o alinhamento com a
   régua de horas não muda. */
a.schedule-element {
  background: var(--ms-block-bg);
  border-radius: 0.625rem;
  overflow: hidden;
  transition: background-color .15s ease;
}


/* A BORDA fica numa regra separada, e mais especifica, de proposito.
   assets/css/fullcalendar.css:1390 traz:
       .fc-time-grid .fc-event, .fc-time-grid .fc-bgevent { border: none !important; }
   Sao dois seletores de classe (0,0,2,0) contra os (0,0,1,1) de
   a.schedule-element - com !important dos dois lados, quem tem mais
   especificidade ganha, independente da ordem dos arquivos. Era por isso que o
   background da regra acima pegava e a borda computava 0px none.
   Prefixar com #schedule-calendar .fc-time-grid resolve sem editar o vendor.

   Esta borda branca E o respiro entre os blocos: como fica DENTRO da caixa,
   dois blocos colados mostram 2x o border-width de branco entre eles.
   Para ajustar o respiro, mexa no border-width daqui. */
#schedule-calendar .fc-time-grid a.schedule-element {
  border-style: solid !important;
  border-color: #FFF !important;
  border-width: 4px !important;
}

/* bloco criado/editado e ainda NAO publicado: tracejado rosa, mais fino que o
   respiro padrao para a moldura nao pesar. A caixa externa e a mesma. */
#schedule-calendar .fc-time-grid a.schedule-element.new-schedule {
  border-style: dashed !important;
  border-color: #FC3A7D !important;
  border-width: 2px !important;
}

a.schedule-element:hover {
  background: var(--ms-block-bg-hover);
}

/* bloco criado/editado e ainda NAO publicado - so o fundo aqui; a borda
   tracejada dele fica na regra de especificidade alta, logo acima. */
a.schedule-element.new-schedule {
  background: #FFF4F8 !important;
}

/* preenche o bloco por offsets em vez de height:100% — assim o rodapé
   (`.weekday`, ancorado em bottom) cai exatamente na borda de baixo,
   independentemente de box-sizing e do padding */
a.schedule-element .fc-content {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  padding: 0.5rem 0.6875rem;
}

/* O fullcalendar patchado inverte nome e horário na marra, com deslocamento
   relativo: `.fc-time{top:30px}` e `.fc-title{top:-38px}` (+ um fundo #F7F7F7 no
   título). Aqui os dois voltam ao fluxo normal e a ordem passa a ser do flex:
   nome em cima, horário embaixo, "Editar" no topo-direito e os dias no
   rodapé-direito. Sem zerar o `top:-38px` o título sai do bloco e o
   `overflow:hidden` o engole. */
a.schedule-element .fc-title {
  order: 1;
  position: static;
  top: auto;
  padding: 0;
  background: transparent;
  display: block;
  /* Reserva a linha do nome MESMO QUANDO ELE VEM VAZIO. Sem isto, playlist que
     não está em $scope.playlists (agendada mas fora do catálogo do cliente)
     colapsa a primeira linha, o horário sobe para o topo e o rótulo de dias vai
     parar embaixo do botão "Editar" — os dois são alinhados à direita. */
  min-height: 1.125rem;
}

/* no print o horário e o rótulo de dias dividem a MESMA linha, horário à
   esquerda e dias à direita — não é o rodapé do bloco */
a.schedule-element .fc-time,
a.schedule-element .fc-time-position {
  order: 2;
  position: static !important;
  top: auto !important;
  padding: 0;
  /* respiro entre a linha do nome e a do horário. Sem isto o rótulo de dias
     encosta no botão "Editar" (os dois são alinhados à direita) e os dois leem
     como um bloco só. No print a distância entre as duas linhas é ~20px. */
  margin-top: 0.5rem;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem;
  visibility: visible !important;
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--ms-txt-500);
  white-space: nowrap;
}

/* O nome da playlist ja tinha `ng-click="openModalPreviewPlaylist()"` no
   template, mas nao parecia clicavel. Em repouso ele fica no texto escuro
   padrao, para nao competir com o resto da grade; a mãozinha e o rosa da marca
   entram no hover, que e quando o clique precisa ficar descoberto. */
a.schedule-element .fc-title .text-limit {
  width: calc(100% - 4.25rem);
  /* espaço para o botão "Editar" */
  max-height: none;
  color: var(--ms-txt-title);
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.00813rem;
  cursor: pointer;
  transition: color .15s ease;
}

a.schedule-element .fc-title .text-limit:hover {
  color: var(--ms-pink);
}

a.schedule-element .fc-time .weekday {
  display: inline-block;
  color: var(--ms-txt-500);
  font-size: 0.625rem;
  font-weight: 500;
  /* alinha com o botão "Editar", que fica logo acima */
  padding-right: 0.125rem;
}

/* Bloco de 1 hora tem ~40px de altura — não cabe nome + horário + dias + botão.
   A classe vem do `isUniqueHour()` que o controller já usava para encolher a
   fonte do nome. O rótulo de dias é o primeiro a sair: é o dado menos crítico e
   é o que colidia com o botão "Editar". */
a.schedule-element--short .fc-content {
  /* 37,5px de bloco - 8px das duas bordas do respiro = 29,5px de caixa. Com
     0,3125rem (5px) em cima e embaixo sobravam 19,5px para duas linhas que
     ocupam 30px, e o `overflow:hidden` cortava a linha do horário ao meio. */
  padding: 0.125rem 0.5rem;
}

a.schedule-element--short .fc-title {
  /* o bloco normal reserva 1.125rem (18px) para a linha do nome; aqui não cabe */
  min-height: 0.8125rem;
}

a.schedule-element--short .fc-title .text-limit {
  font-size: 0.6875rem;
  line-height: 1.15;
}

a.schedule-element--short .fc-time,
a.schedule-element--short .fc-time-position {
  font-size: 0.625rem;
  /* no bloco de 1 hora nao ha altura para o respiro do bloco normal */
  margin-top: 0.0625rem;
  /* o line-height de 19px vem herdado do fullcalendar e nao do font-size: sem
     travar aqui, a linha do horario sozinha ocupa 19px dos 26px uteis e o
     `overflow:hidden` do bloco cortava os numeros pela metade. */
  line-height: 1.1;
}

a.schedule-element--short .fc-time span {
  line-height: 1.1;
}

a.schedule-element--short .fc-time .weekday {
  display: none;
}

a.schedule-element--short .schedule-playlist-menu-dropdown {
  height: 1.0625rem;
  font-size: 0.5625rem;
}

a.schedule-element--short .btn-calendar {
  top: 0.25rem !important;
}

/* --- botão "Editar" (abre o popover de 4 ações — comportamento intacto) --- */

/* A setinha do popover sai: com a lista de 4 ações logo abaixo do botão, ela não
   ajuda a entender de onde o menu veio e ainda lia como um "ícone de seta pra
   cima" solto dentro das opções.
   `customClass: 'ms-schedule-popover'` é posto no `initPopover`, para isto valer
   só neste popover e não nos das outras telas. No Bootstrap 5 a seta é
   `.popover-arrow` (era `.arrow` no 4.x).
   O `margin-top` compensa o espaço que a seta reservava. */
.ms-schedule-popover .popover-arrow {
  display: none;
}

.ms-schedule-popover {
  margin-top: -0.25rem;
}

.schedule-playlist-menu-dropdown {
  width: auto;
  height: 1.25rem;
  padding: 0 0.4375rem;
  gap: 0.25rem;
  border-radius: 0.3125rem;
  border: 1px solid #E2D3DA;
  background: #FFF;
  color: var(--ms-txt-500);
  font-size: 0.625rem;
  font-weight: 500;
  line-height: 1;
}

.schedule-playlist-menu-dropdown svg path {
  fill: currentColor;
}

.btn-calendar {
  top: 0.4375rem !important;
  right: 0.5rem !important;
}

/* --- cabeçalho dos dias --- */

.fc-day-header {
  color: var(--ms-txt-500);
  font-weight: 500;
}

/* --------------------------------------------------------------------------
   7. Responsivo
   -------------------------------------------------------------------------- */

@media (max-width: 1366px) {
  .ms-header .box-dropdown-unity {
    min-width: 17rem;
  }

  .ms-btn {
    padding: 0 0.875rem;
  }

  .ms-now-card__meta {
    gap: 0.25rem 0.75rem;
  }
}

/* sem largura para a onda, o texto do card vem primeiro */
@media (max-width: 1200px) {
  .ms-waveform {
    display: none;
  }
}

@media (max-width: 991px) {
  .ms-header {
    align-items: flex-start;
  }

  .ms-header-actions {
    width: 100%;
    justify-content: flex-start;
  }

  .ms-header .box-dropdown-unity {
    min-width: 0;
    flex: 1 1 100%;
    max-width: none;
  }

  .ms-now-strip {
    flex-direction: column;
  }

  .ms-now-card--current,
  .ms-now-card--next {
    flex: 1 1 auto;
  }

  .ms-now-card--next .ms-now-card__name {
    -webkit-line-clamp: 2;
  }
}

/* --------------------------------------------------------------------------
   8. Geometria da grade — derivada do mockup NovaTela.png

   O mockup está a 60% (medido: a palavra "Segunda" tem 33px nele e 55px no
   render real => fator 1,6667). Convertendo as medidas do print:

     hora .................. 22,5px no print -> 37,5px reais
     banda de 6 horas ...... 135px  -> 225px
     gap entre bandas ......   5px  ->   8,33px
     régua de horas ........  20px  ->  33,3px de largura
     coluna de períodos ....  96px  -> 160px
     linha de cabeçalho ....  40px  ->  66,7px
     respiro à direita .....  16px  ->  26,7px
     respiro inferior ......  19px  ->  31,7px

   Tudo abaixo sai destas variáveis — mudar a escala é mexer só aqui.

   Isto SUBSTITUI as 78 regras px de `assets/css/fullcalendar.css:16-328`
   (inclusive o bloco @media max-width:1366px, que deixa de ser necessário
   porque o eixo horizontal virou porcentagem). Aquele arquivo não foi editado:
   como este CSS carrega depois e usa a mesma especificidade + !important,
   ganha no cascade.
   -------------------------------------------------------------------------- */

:root {
  --ms-hour-h: 37.5px;
  /* 8px para bater EXATAMENTE com o respiro entre blocos (2 x border-width de
     4px). Era 8.33px, medido do mockup a 60%; a diferenca de 0.33px nao aparece
     e a uniformidade do espacamento vale mais (pedido do Anderson em 18/08). */
  --ms-band-gap: 8px;
  --ms-band-h: calc(var(--ms-hour-h) * 6);
  --ms-band-pitch: calc(var(--ms-band-h) + var(--ms-band-gap));
  --ms-grid-h: calc(var(--ms-band-pitch) * 4 - var(--ms-band-gap));

  --ms-head-h: 66.7px;
  --ms-ruler-w: 33.3px;
  --ms-ruler-gap: 8.3px;
  --ms-periods-w: 160px;
  --ms-grid-pad-right: 26.7px;
  --ms-grid-pad-bottom: 31.7px;
}

/* --- caixa da grade --- */

.delimiter-board-musical-schedule {
  height: auto;
  padding-bottom: var(--ms-grid-pad-bottom);
  align-items: flex-start;
}

.periods-info {
  width: var(--ms-periods-w);
  height: auto;
  padding: 0;
  flex: 0 0 auto;
}

.periods-info ul {
  height: auto;
  gap: var(--ms-band-gap);
}

/* "Horários" ocupa exatamente a linha do cabeçalho dos dias, para os dois
   textos nascerem na mesma altura */
.periods-info ul li.turnos {
  height: var(--ms-head-h);
  margin-bottom: 0 !important;
  justify-content: center;
}

.periods-info-list {
  height: var(--ms-band-h);
  margin-bottom: 0;
  justify-content: center;
}

#schedule-calendar {
  height: auto;
  flex: 1 1 auto;
  min-width: 0;
}

/* nasce `display:flex` (main.css:2767); como flex item, a <table> não encolhe
   abaixo do conteúdo (min-width:auto) e os blocos vazavam à direita */
.table-musical-schedule {
  display: block;
  /* sem border-box o padding some para fora e os blocos vazam à direita */
  box-sizing: border-box;
  height: auto;
  width: 100%;
  /* o padding-left reserva a faixa da régua, que é posicionada por cima */
  padding: 0 var(--ms-grid-pad-right) 0 calc(var(--ms-ruler-w) + var(--ms-ruler-gap));
}

.table-musical-schedule > table {
  width: 100%;
  min-width: 0;
  table-layout: fixed;
}

/* --- linha de cabeçalho dos dias --- */

#schedule-calendar .fc-head td.fc-widget-header,
#schedule-calendar .fc-head .fc-row.fc-widget-header {
  height: var(--ms-head-h);
  padding: 0;
}

#schedule-calendar .fc-head .fc-row.fc-widget-header > table {
  width: 100%;
  height: 100%;
  table-layout: fixed;
}

#schedule-calendar .fc-day-header {
  height: var(--ms-head-h);
  /* line-height centraliza na linha sem depender de vertical-align, que o
     fullcalendar sobrescreve para o topo */
  line-height: var(--ms-head-h);
  /* no mockup os dias são alinhados à esquerda da própria coluna */
  text-align: left;
  margin-bottom: 0;
  padding: 0;
}

/* --- régua de horas --- */

.period-musical-schedule-position {
  top: var(--ms-head-h);
  left: 0;
}

.periods-musical-schedule {
  width: var(--ms-ruler-w);
  gap: var(--ms-band-gap);
  padding: 0;
}

.periods-musical-schedule .shift {
  height: var(--ms-band-h);
  justify-content: flex-start;
}

.periods-musical-schedule .shift span {
  height: var(--ms-hour-h);
  margin-bottom: 0;
  line-height: var(--ms-hour-h);
}

/* --- área dos blocos --- */

/* O rosa é de CADA PLAYLIST, não do componente: a área dos 7 dias é branca e
   cada bloco agendado desenha o próprio retângulo rosa arredondado.
   A separação entre blocos vizinhos (o de baixo na mesma coluna, o da coluna
   ao lado) é o branco do fundo aparecendo pela borda de 2px de
   `a.schedule-element` — ver "blocos de playlist agendada".
   Consequência assumida: grade vazia = área branca, e não mais um retângulo
   rosa como na versão anterior. */
#schedule-calendar .fc-time-grid-container {
  height: var(--ms-grid-h);
  overflow: visible;
  background: #FFF;
}

/* `.fc-time-grid` é um div em fluxo cujo único filho (o skeleton) é absoluto,
   então ele colapsa para 0 — e o `bottom:0` do skeleton resolveria contra nada */
#schedule-calendar .fc-time-grid {
  height: 100%;
}

#schedule-calendar .fc-time-grid-container > .fc-time-grid > .fc-content-skeleton > table,
#schedule-calendar .fc-time-grid-container > .fc-time-grid > .fc-content-skeleton > table > tbody,
#schedule-calendar .fc-time-grid-container > .fc-time-grid > .fc-content-skeleton > table > tbody > tr,
#schedule-calendar .fc-time-grid-container > .fc-time-grid > .fc-content-skeleton > table > tbody > tr > td {
  height: 100%;
  padding: 0;
}

/* o skeleton nasce `absolute` com top/left/right e sem bottom, então colapsa
   junto com a tabela vazia lá dentro. Com bottom:0 ele passa a ter a altura da
   grade, e o container dos eventos vira o retângulo de referência dos blocos —
   é isso que permite posicionar por px de hora em vez dos offsets negativos
   que o fullcalendar patchado usava. */
#schedule-calendar .fc-time-grid .fc-content-skeleton {
  bottom: 0;
}

#schedule-calendar .fc-time-grid .fc-event-container {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: 0;
}


/* --- espacamento uniforme entre blocos ------------------------------------
   O respiro padrao entre dois blocos vem das duas bordas brancas: 4px + 4px = 8px.
   Na fronteira de turno (madrugada|manha, manha|tarde, tarde|noite) existe AINDA
   o `--ms-band-gap` da geometria da grade, que e o mesmo vao usado pela regua de
   horas e pela coluna de periodos. Somando os tres, aquela juncao ficava com 16px
   contra 8px de todas as outras — foi o que o Anderson viu.

   Solucao: nas fronteiras internas de turno o bloco nao desenha a borda daquele
   lado; o vao fica sendo so o `--ms-band-gap` (8px). Assim TODOS os espacamentos
   — horizontal, vertical dentro do turno e vertical entre turnos — dao 8px.

   Bloco que ATRAVESSA a fronteira (ex.: 00:00-07:59) nao casa com nenhum destes
   seletores: ele mantem as bordas e cobre o vao com o proprio rosa, como deve.
   O `border-radius` continua valendo — zerar a largura nao tira o arredondamento.
   As bordas de fora da grade (hour-start-00 e hour-end-23) ficam intactas. */
#schedule-calendar .fc-time-grid a.schedule-element.hour-start-06,
#schedule-calendar .fc-time-grid a.schedule-element.hour-start-12,
#schedule-calendar .fc-time-grid a.schedule-element.hour-start-18 {
  border-top-width: 0 !important;
}

#schedule-calendar .fc-time-grid a.schedule-element.hour-end-05,
#schedule-calendar .fc-time-grid a.schedule-element.hour-end-11,
#schedule-calendar .fc-time-grid a.schedule-element.hour-end-17 {
  border-bottom-width: 0 !important;
}

/* --- tooltip do bloco -----------------------------------------------------
   O bloco tem `overflow:hidden` e, nos curtos, a variante `--short` chega a
   esconder o rotulo de dias - o tooltip garante o dado completo. Delegado a
   partir de `#music-programming-schedule` (ver initScheduleBlockTooltips no
   PlaylistController) com `container: body`, senao o proprio overflow do bloco
   cortaria o balao.

   ATENCAO - a versao aqui e BOOTSTRAP 5.3.3 (o `bootstrap.min.js` diz v5.3.3;
   a API jQuery `$(el).tooltip()` continua existindo so porque o BS5 registra a
   ponte quando `window.jQuery` esta presente, que e o caso). Duas consequencias
   que nao valem para exemplos de BS4 espalhados por ai:
     - a seta e `.tooltip-arrow`, nao `.arrow`;
     - a superficie e controlada por CSS VARIABLES (`--bs-tooltip-*`), entao
       redefinir as variaveis e mais robusto do que brigar com os seletores -
       e a cor da seta vem de brinde, porque o proprio Bootstrap faz
       `border-*-color: var(--bs-tooltip-bg)`.

   O conteudo e HTML montado no controller a partir dos `data-tip-*` do bloco,
   entao da para estilizar estrutura de verdade e nao uma linha de texto:
   superficie grafite da marca, faixa de gradiente rosa no topo como assinatura,
   nome em destaque, horario e dias numa linha secundaria separados por um ponto,
   e pilula rosa quando o bloco ainda nao foi publicado. */
.ms-block-tooltip {
  --bs-tooltip-bg: var(--ms-graphite);
  --bs-tooltip-color: #FFF;
  /* 0.9 e o padrao e deixa a superficie grafite lavada */
  --bs-tooltip-opacity: 1;
  --bs-tooltip-max-width: 17rem;
  --bs-tooltip-padding-x: 0;
  --bs-tooltip-padding-y: 0;
  --bs-tooltip-border-radius: 0.625rem;
  --bs-tooltip-font-size: 0.75rem;
  font-family: 'Inter', sans-serif;
}

.ms-block-tooltip .tooltip-inner {
  text-align: left;
  box-shadow: 0 0.5rem 1.5rem 0 rgba(0, 0, 0, 0.22);
  /* recorta a faixa de gradiente nos cantos arredondados */
  overflow: hidden;
}

.ms-tip {
  position: relative;
  padding: 0.6875rem 0.75rem;
}

/* assinatura da marca: o mesmo gradiente do botao "Agendar e publicar" */
.ms-tip::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 0.1875rem;
  background: var(--ms-pink-gradient);
}

.ms-tip__name {
  display: block;
  color: #FFF;
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.00875rem;
}

.ms-tip__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.375rem;
  margin-top: 0.25rem;
  color: rgba(255, 255, 255, 0.72);
  font-size: 0.75rem;
  font-weight: 400;
  line-height: 1.3;
}

.ms-tip__dot {
  width: 0.1875rem;
  height: 0.1875rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.4);
}

.ms-tip__flag {
  display: inline-block;
  margin-top: 0.5rem;
  padding: 0.0625rem 0.5rem;
  border-radius: 62.4375rem;
  background: var(--ms-pink-gradient);
  color: #FFF;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.5;
}

/* --- posicionamento dos blocos --- */

.hour-base {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 1;
}

/* topo de cada hora: banda * turno + altura da hora * posicao dentro do turno */
.hour-start-0,
.hour-start-00 {
  top: 0 !important;
}

.hour-start-01 {
  top: calc(var(--ms-hour-h) * 1) !important;
}

.hour-start-02 {
  top: calc(var(--ms-hour-h) * 2) !important;
}

.hour-start-03 {
  top: calc(var(--ms-hour-h) * 3) !important;
}

.hour-start-04 {
  top: calc(var(--ms-hour-h) * 4) !important;
}

.hour-start-05 {
  top: calc(var(--ms-hour-h) * 5) !important;
}

.hour-start-06 {
  top: calc(var(--ms-band-pitch) * 1) !important;
}

.hour-start-07 {
  top: calc(var(--ms-band-pitch) * 1 + var(--ms-hour-h) * 1) !important;
}

.hour-start-08 {
  top: calc(var(--ms-band-pitch) * 1 + var(--ms-hour-h) * 2) !important;
}

.hour-start-09 {
  top: calc(var(--ms-band-pitch) * 1 + var(--ms-hour-h) * 3) !important;
}

.hour-start-10 {
  top: calc(var(--ms-band-pitch) * 1 + var(--ms-hour-h) * 4) !important;
}

.hour-start-11 {
  top: calc(var(--ms-band-pitch) * 1 + var(--ms-hour-h) * 5) !important;
}

.hour-start-12 {
  top: calc(var(--ms-band-pitch) * 2) !important;
}

.hour-start-13 {
  top: calc(var(--ms-band-pitch) * 2 + var(--ms-hour-h) * 1) !important;
}

.hour-start-14 {
  top: calc(var(--ms-band-pitch) * 2 + var(--ms-hour-h) * 2) !important;
}

.hour-start-15 {
  top: calc(var(--ms-band-pitch) * 2 + var(--ms-hour-h) * 3) !important;
}

.hour-start-16 {
  top: calc(var(--ms-band-pitch) * 2 + var(--ms-hour-h) * 4) !important;
}

.hour-start-17 {
  top: calc(var(--ms-band-pitch) * 2 + var(--ms-hour-h) * 5) !important;
}

.hour-start-18 {
  top: calc(var(--ms-band-pitch) * 3) !important;
}

.hour-start-19 {
  top: calc(var(--ms-band-pitch) * 3 + var(--ms-hour-h) * 1) !important;
}

.hour-start-20 {
  top: calc(var(--ms-band-pitch) * 3 + var(--ms-hour-h) * 2) !important;
}

.hour-start-21 {
  top: calc(var(--ms-band-pitch) * 3 + var(--ms-hour-h) * 3) !important;
}

.hour-start-22 {
  top: calc(var(--ms-band-pitch) * 3 + var(--ms-hour-h) * 4) !important;
}

.hour-start-23 {
  top: calc(var(--ms-band-pitch) * 3 + var(--ms-hour-h) * 5) !important;
}

/* base de cada hora, medida a partir do fundo da grade */
.hour-end-0,
.hour-end-00 {
  bottom: calc(var(--ms-grid-h) - var(--ms-hour-h)) !important;
}

.hour-end-01 {
  bottom: calc(var(--ms-grid-h) - var(--ms-hour-h) * 2) !important;
}

.hour-end-02 {
  bottom: calc(var(--ms-grid-h) - var(--ms-hour-h) * 3) !important;
}

.hour-end-03 {
  bottom: calc(var(--ms-grid-h) - var(--ms-hour-h) * 4) !important;
}

.hour-end-04 {
  bottom: calc(var(--ms-grid-h) - var(--ms-hour-h) * 5) !important;
}

.hour-end-05 {
  bottom: calc(var(--ms-grid-h) - var(--ms-hour-h) * 6) !important;
}

.hour-end-06 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 1 - var(--ms-hour-h)) !important;
}

.hour-end-07 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 1 - var(--ms-hour-h) * 2) !important;
}

.hour-end-08 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 1 - var(--ms-hour-h) * 3) !important;
}

.hour-end-09 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 1 - var(--ms-hour-h) * 4) !important;
}

.hour-end-10 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 1 - var(--ms-hour-h) * 5) !important;
}

.hour-end-11 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 1 - var(--ms-hour-h) * 6) !important;
}

.hour-end-12 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 2 - var(--ms-hour-h)) !important;
}

.hour-end-13 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 2 - var(--ms-hour-h) * 2) !important;
}

.hour-end-14 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 2 - var(--ms-hour-h) * 3) !important;
}

.hour-end-15 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 2 - var(--ms-hour-h) * 4) !important;
}

.hour-end-16 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 2 - var(--ms-hour-h) * 5) !important;
}

.hour-end-17 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 2 - var(--ms-hour-h) * 6) !important;
}

.hour-end-18 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 3 - var(--ms-hour-h)) !important;
}

.hour-end-19 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 3 - var(--ms-hour-h) * 2) !important;
}

.hour-end-20 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 3 - var(--ms-hour-h) * 3) !important;
}

.hour-end-21 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 3 - var(--ms-hour-h) * 4) !important;
}

.hour-end-22 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 3 - var(--ms-hour-h) * 5) !important;
}

.hour-end-23 {
  bottom: calc(var(--ms-grid-h) - var(--ms-band-pitch) * 3 - var(--ms-hour-h) * 6) !important;
}

/* colunas dos dias em porcentagem: exatas em qualquer largura, e tornam
   desnecessario o bloco @media max-width:1366px do fullcalendar.css */
.week-day-start-seg {
  left: 0 !important;
}

.week-day-start-ter {
  left: calc(100% / 7 * 1) !important;
}

.week-day-start-qua {
  left: calc(100% / 7 * 2) !important;
}

.week-day-start-qui {
  left: calc(100% / 7 * 3) !important;
}

.week-day-start-sex {
  left: calc(100% / 7 * 4) !important;
}

.week-day-start-sab {
  left: calc(100% / 7 * 5) !important;
}

.week-day-start-dom {
  left: calc(100% / 7 * 6) !important;
}

.week-day-end-seg {
  right: calc(100% / 7 * 6) !important;
}

.week-day-end-ter {
  right: calc(100% / 7 * 5) !important;
}

.week-day-end-qua {
  right: calc(100% / 7 * 4) !important;
}

.week-day-end-qui {
  right: calc(100% / 7 * 3) !important;
}

.week-day-end-sex {
  right: calc(100% / 7 * 2) !important;
}

.week-day-end-sab {
  right: calc(100% / 7 * 1) !important;
}

.week-day-end-dom {
  right: 0 !important;
}


/* --------------------------------------------------------------------------
   9. Skeletons de carregamento (PD-66, 19/08)

   Esta tela leva dezenas de segundos para popular contra o banco de dev — o
   `GetPlaylistsPortal` sozinho passa de 30 s e é ele que segura o `Promise.all`
   do `setCalendar`. Até 19/08 isso era coberto pelo loader de tela cheia do
   `$rootScope.loadingFullScreen`, que apaga a página inteira atrás de um véu
   cinza e não diz o que está vindo.

   Agora a grade e os dois cards desenham a própria forma enquanto esperam.
   O loader de tela cheia continua no "Agendar e publicar", onde a ação é
   bloqueante de propósito.
   -------------------------------------------------------------------------- */

:root {
  --ms-sk-base: #EFEFEF;
  --ms-sk-shine: #F9F9F9;
}

.ms-sk {
  display: block;
  border-radius: var(--ms-radius);
  background-color: var(--ms-sk-base);
  /* o brilho corre da esquerda para a direita; `background-size` maior que o
     elemento é o que dá o deslocamento */
  background-image: linear-gradient(90deg,
      var(--ms-sk-base) 0%,
      var(--ms-sk-shine) 50%,
      var(--ms-sk-base) 100%);
  background-size: 200% 100%;
  background-repeat: no-repeat;
  animation: ms-sk-shimmer 1.4s linear infinite;
}

@keyframes ms-sk-shimmer {
  from {
    background-position: 200% 0;
  }

  to {
    background-position: -200% 0;
  }
}

/* --- skeleton da faixa de cards --- */

.ms-now-strip--skeleton .ms-now-card__info {
  gap: 0.625rem;
  justify-content: center;
}

.ms-sk--thumb {
  width: 100%;
  height: 100%;
  border-radius: inherit;
}

.ms-sk--pill {
  width: 7.5rem;
  height: 1.25rem;
  border-radius: 62.4375rem;
}

.ms-sk--title {
  width: 60%;
  min-width: 9rem;
  height: 1.375rem;
}

.ms-sk--line {
  width: 45%;
  min-width: 7rem;
  height: 0.875rem;
}

.ms-sk--line--wide {
  width: 70%;
}

/* ocupa o mesmo espaço da onda, com a mesma conta de largura */
.ms-sk--wave {
  flex: 0 1 calc(var(--ms-wave-bar-w) * 40 + var(--ms-wave-gap) * 39);
  align-self: center;
  height: calc(var(--ms-wave-h) * 0.6);
  min-width: 0;
}

/* --- skeleton da grade --- */

.ms-grid-skeleton {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: row;
  /* z-index baixo: se por qualquer motivo os blocos reais chegarem antes de o
     ng-if desligar, quem aparece por cima é o conteúdo de verdade */
  z-index: 0;
}

.ms-grid-skeleton__col {
  display: flex;
  flex-direction: column;
  /* as 7 colunas dos dias, na mesma divisão do `calc(100% / 7)` dos blocos */
  flex: 1 1 calc(100% / 7);
  min-width: 0;
  gap: 8px;
  padding: 4px;
}

.ms-grid-skeleton__col > .ms-sk {
  flex-basis: 0;
  min-height: 0;
}

@media (prefers-reduced-motion: reduce) {

  .ms-sk {
    animation: none;
  }
}

/* a onda some abaixo de 1200px; o placeholder dela acompanha */
@media (max-width: 1199.98px) {
  .ms-sk--wave {
    display: none;
  }
}

/* ===========================================================================
   9. Capa ausente / capa que nao carregou   (PD-66, 21/08)

   Uma arte so para os dois estados: "playlist sem capa" (`.ms-now-card__thumb-empty`,
   no template) e "a capa quebrou" (`.ms-img-fallback`, posta pela diretiva
   `imgFallback` em directives/ImageFallbackDirective.js). A nota musical e a mesma
   do icone "Total de Musicas" do card, so que ampliada — mantem o vocabulario visual
   da tela sem depender de nenhum arquivo de imagem (o SVG vai inline no data URI,
   entao nao ha um segundo request para quebrar).
   =========================================================================== */

:root {
  --ms-cover-placeholder:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 96'%3E%3Cdefs%3E%3ClinearGradient id='msph' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%23F4F4F6'/%3E%3Cstop offset='1' stop-color='%23DBDBE1'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='96' height='96' fill='url(%23msph)'/%3E%3Cg transform='translate(24 22) scale(3.43)' fill='%23AFAFBC'%3E%3Cpath d='M12.25 0.583C12.106 0.466 11.918 0.42 11.737 0.457L5.32 1.79C5.045 1.847 4.848 2.09 4.848 2.371V9.567C4.44 9.313 3.958 9.167 3.442 9.167C1.978 9.167 0.787 10.344 0.787 11.792C0.787 13.239 1.978 14.417 3.442 14.417C4.906 14.417 6.097 13.239 6.097 11.792V4.9L11.265 3.826V7.817C10.857 7.563 10.375 7.417 9.859 7.417C8.395 7.417 7.204 8.594 7.204 10.042C7.204 11.489 8.395 12.667 9.859 12.667C11.323 12.667 12.514 11.489 12.514 10.042V1.167C12.514 0.938 12.394 0.7 12.25 0.583Z'/%3E%3C/g%3E%3C/svg%3E");
}

.ms-now-card__thumb-empty,
.ms-img-fallback {
  background: var(--ms-cover-placeholder) center / cover no-repeat;
}

/* A diretiva troca o src por um GIF 1x1: sem isto o <img> colapsaria para 1px e
   o placeholder nao teria area para aparecer. Vale para as capas dos modais desta
   tela, que nao tem largura fixa. */
img.ms-img-fallback {
  width: 100%;
  height: 100%;
  min-width: 3rem;
  min-height: 3rem;
  object-fit: cover;
}

/* nos cards a caixa ja e o quadrado de --ms-card-media-h */
.ms-now-card__thumb img.ms-img-fallback {
  min-width: 0;
  min-height: 0;
}

/* ===========================================================================
   10. Aviso "aguardando o player"   (PD-66, 21/08)

   Depois de "Agendar e publicar", o player so troca de playlist no proximo check
   — a propria toast do save promete "em ate 5 minutos". Ate la o card mostra o que
   o player REALMENTE esta tocando (a playlist antiga), o que sem explicacao parece
   tela desatualizada. Este aviso aparece so nessa janela; some sozinho quando o
   player confirma a agenda (o polling de 60s reavalia).
   =========================================================================== */

.ms-now-sync {
  display: flex;
  align-items: flex-start;
  gap: 0.375rem;
  margin-top: 0.375rem;
  padding: 0.3125rem 0.5rem;
  border-radius: var(--ms-radius);
  border: 1px solid #F3D7A6;
  background: #FDF6E7;
  color: #8A6520;
  font-family: 'Inter';
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.35;
  letter-spacing: 0;
}

.ms-now-sync svg {
  flex: 0 0 auto;
  margin-top: 0.0625rem;
}

/* o card da direita e estreito; o aviso so faz sentido no "Tocando agora" */
.ms-now-card--next .ms-now-sync {
  display: none;
}
